home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / 3wave23.zip / CAPTURE.DIF < prev    next >
Text File  |  1996-10-14  |  110KB  |  3,990 lines

  1. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/charset.txt src/charset.txt
  2. --- v106qc/charset.txt    Wed Dec 31 19:00:00 1969
  3. +++ src/charset.txt    Mon Oct 14 01:49:38 1996
  4. @@ -0,0 +1,25 @@
  5. +/*
  6. +Earth Magic     = ┼ß≥⌠Φ ═ßτΘπ
  7. +Resistance      = ╥σ≤Θ≤⌠ßεπσ
  8. +Black Magic     = ┬∞πßδ ═ßτΘπ
  9. +Strength        = ╙⌠≥σετ⌠Φ
  10. +Hell Magic      = ╚σ∞∞ ═ßτΘπ
  11. +Haste           = ╚ß≤⌠σ
  12. +Elder Magic     = ┼∞Σσ≥ ═ßτΘπ
  13. +Regeneration    = ╥στσεσ≥ß⌠Θ∩ε
  14. +BLUE            = ┬╠╒┼
  15. +RED             = ╥┼─
  16. +YOU GOT THE ENEMY FLAG = ┘╧╒ ╟╧╘ ╘╚┼ ┼╬┼═┘ ╞╠┴╟
  17. +RETURN TO BASE = ╥┼╘╒╥╬ ╘╧ ┬┴╙┼
  18. +CAPTURE THE FLAG = ├┴╨╘╒╥┼ ╘╚┼ ╞╠┴╟
  19. +captured        = πß≡⌠⌡≥σΣ
  20. +got             = τ∩⌠
  21. +lost            = ∞∩≤⌠
  22. +returned        = ≥σ⌠⌡≥εσΣ
  23. +
  24. +ABCDEFGHIJKLMNOPQRSTUVWXYZ
  25. +┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌
  26. +
  27. +abcdefghijklmnopqrstuvwxyz
  28. +ßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙√
  29. +*/
  30. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/client.qc src/client.qc
  31. --- v106qc/client.qc    Sun Sep 29 23:29:00 1996
  32. +++ src/client.qc    Mon Oct 14 01:04:43 1996
  33. @@ -6,9 +6,67 @@
  34.  void() player_stand1;
  35.  void (vector org) spawn_tfog;
  36.  void (vector org, entity death_owner) spawn_tdeath;
  37. +string(string old) RandomLevel;
  38.  
  39.  float    modelindex_eyes, modelindex_player;
  40.  
  41. +void() MOTD =
  42. +{
  43. +    if (self.motd_count < 5) {
  44. +        self.motd_time = time + 1;
  45. +        self.motd_count = self.motd_count + 1;
  46. +        if (teamplay & TEAM_CAPTURE_FLAG) 
  47. +            if (self.team == TEAM_COLOR1 + 1)
  48. +                centerprint(self, "Welcome to Quake.ThreeWave.COM\nYour admin is Zoid.\n\n├┴╨╘╒╥┼ ╘╚┼ ╞╠┴╟!\n\nYou are ╥┼─ team\n"); //red
  49. +            else
  50. +                centerprint(self, "Welcome to Quake.ThreeWave.COM\nYour admin is Zoid.\n\n├┴╨╘╒╥┼ ╘╚┼ ╞╠┴╟!\n\nYou are ┬╠╒┼ team"); //blue
  51. +        else if (teamplay)
  52. +            centerprint(self, "Welcome to Quake.ThreeWave.COM\nYour admin is Zoid.\n\nTEAMPLAY IS ACTIVE");
  53. +        else
  54. +            centerprint(self, "Welcome to Quake.ThreeWave.COM\nYour admin is Zoid.");
  55. +        return;
  56. +    } else {
  57. +        sprint(self, "Info: http://quake.threewave.com/\n");
  58. +        if (teamplay)
  59. +            sprint(self, "Impulse 25 for Team Settings\n");
  60. +        if (teamplay & TEAM_CAPTURE_FLAG)
  61. +            sprint(self, "You are playing ├┴╨╘╒╥┼ ╘╚┼ ╞╠┴╟!\n"); // CAPTURE THE FLAG
  62. +    }
  63. +    self.motd_time = 0;
  64. +};
  65. +
  66. +// ZOID: with several effects doing the dimlight thing, they just can't
  67. +// turn it off.  Do not set self.effects with EF_DIMLIGHT directly.  This
  68. +// will automatically do it when CheckPowerups is called
  69. +// EF_DIMLIGHT is used;
  70. +// 1. Invincible (Pentagram)
  71. +// 2. Super Damage (Quad Power)
  72. +// 3. Having Flag in Capture
  73. +// 4. On fire (flamethrower)
  74. +// self is player
  75. +void () CheckDimLight = {
  76. +    local float flag;
  77. +
  78. +    flag = 0;
  79. +    // invincable
  80. +    if (self.invincible_finished > time)
  81. +        flag = 1;
  82. +    // quad
  83. +    if (self.super_damage_finished > time)
  84. +        flag = 1;
  85. +    // flag
  86. +    if (self.player_flag & ITEM_ENEMY_FLAG)
  87. +        flag = 1;
  88. +    // On fire
  89. +    if (self.onfire)
  90. +        flag = 1;
  91. +
  92. +    if (flag)
  93. +        self.effects = self.effects | EF_DIMLIGHT;
  94. +    else
  95. +        self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  96. +};
  97. +
  98.  /*
  99.  =============================================================================
  100.  
  101. @@ -59,11 +117,14 @@
  102.      parm7 = self.ammo_cells;
  103.      parm8 = self.weapon;
  104.      parm9 = self.armortype * 100;
  105. +// *TEAMPLAY*
  106. +    parm10 = self.lastteam;    // Save the current team of the player
  107. +    parm16 = self.player_flag;
  108.  };
  109.  
  110.  void() SetNewParms =
  111.  {
  112. -    parm1 = IT_SHOTGUN | IT_AXE;
  113. +    parm1 = IT_SHOTGUN | IT_AXE | IT_HOOK;
  114.      parm2 = 100;
  115.      parm3 = 0;
  116.      parm4 = 25;
  117. @@ -72,10 +133,21 @@
  118.      parm7 = 0;
  119.      parm8 = 1;
  120.      parm9 = 0;
  121. +// *TEAMPLAY*
  122. +    parm10 = -1;    // Reset 
  123. +    parm16 = 0;
  124.  };
  125.  
  126.  void() DecodeLevelParms =
  127.  {
  128. +    self.player_flag = parm16;
  129. +    self.player_flag = self.player_flag - (self.player_flag & ITEM_RUNE_MASK);
  130. +    self.player_flag = self.player_flag - (self.player_flag & ITEM_ENEMY_FLAG);
  131. +    if (teamplay == 0)
  132. +        self.skin = (self.player_flag & 65280)/256;
  133. +    else
  134. +        self.skin = 0; // default to the Quake dude
  135. +
  136.      if (serverflags)
  137.      {
  138.          if (world.model == "maps/start.bsp")
  139. @@ -91,6 +163,9 @@
  140.      self.ammo_cells = parm7;
  141.      self.weapon = parm8;
  142.      self.armortype = parm9 * 0.01;
  143. +// *TEAMPLAY*
  144. +    if(TeamColorIsLegal(parm10 - 1))
  145. +        self.lastteam = parm10;
  146.  };
  147.  
  148.  /*
  149. @@ -258,7 +333,7 @@
  150.      
  151.  // enforce a wait time before allowing changelevel
  152.      if (deathmatch)
  153. -        intermission_exittime = time + 5;
  154. +        intermission_exittime = time + 8;
  155.      else
  156.          intermission_exittime = time + 2;
  157.  
  158. @@ -294,6 +369,9 @@
  159.      if (other.classname != "player")
  160.          return;
  161.  
  162. +    if ((cvar("noexit") == 1) && (teamplay & TEAM_CAPTURE_FLAG))
  163. +        return;
  164. +
  165.      if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start")))
  166.      {
  167.          T_Damage (other, self, self, 50000);
  168. @@ -306,6 +384,10 @@
  169.          bprint (" exited the level\n");
  170.      }
  171.      
  172. +// ZOID - go to next level randomly
  173. +    if (deathmatch)
  174. +        nextmap = RandomLevel(mapname);
  175. +    else
  176.      nextmap = self.map;
  177.  
  178.      SUB_UseTargets ();
  179. @@ -384,11 +466,25 @@
  180.  */
  181.  void() ClientKill =
  182.  {
  183. +    if (self.suicide_count > 3) {
  184. +        sprint(self, "You have suicided too much already.\n");
  185. +        return;
  186. +    }
  187.      bprint (self.netname);
  188.      bprint (" suicides\n");
  189. +    DropRune();
  190. +    TeamCaptureDropFlag();
  191.      set_suicide_frame ();
  192.      self.modelindex = modelindex_player;
  193.      self.frags = self.frags - 2;    // extra penalty
  194. +    self.suicide_count = self.suicide_count + 1;
  195. +    respawn ();
  196. +};
  197. +
  198. +void() SilentKill =
  199. +{
  200. +    set_suicide_frame ();
  201. +    self.modelindex = modelindex_player;
  202.      respawn ();
  203.  };
  204.  
  205. @@ -407,8 +503,6 @@
  206.  entity() SelectSpawnPoint =
  207.  {
  208.      local    entity spot;
  209. -    local    entity thing;
  210. -    local    float  pcount;
  211.      
  212.  // testinfo_player_start is only found in regioned levels
  213.      spot = find (world, classname, "testplayerstart");
  214. @@ -426,29 +520,16 @@
  215.      }
  216.      else if (deathmatch)
  217.      {
  218. -        spot = lastspawn;
  219. -        while (1)
  220. -        {
  221. -            spot = find(spot, classname, "info_player_deathmatch");
  222. +        if (!self.killed) {
  223. +            spot = TeamCaptureSpawn();
  224.              if (spot != world)
  225. -            {
  226. -                if (spot == lastspawn)
  227. -                    return lastspawn;
  228. -                pcount = 0;
  229. -                thing = findradius(spot.origin, 32);
  230. -                while(thing)
  231. -                {
  232. -                    if (thing.classname == "player")
  233. -                        pcount = pcount + 1;
  234. -                    thing = thing.chain;
  235. -                }
  236. -                if (pcount == 0)
  237. -                {
  238. -                    lastspawn = spot;
  239.                      return spot;
  240.                  }
  241. -            }
  242. -        }
  243. +        lastspawn = find(lastspawn, classname, "info_player_deathmatch");
  244. +        if (lastspawn == world)
  245. +            lastspawn = find (lastspawn, classname, "info_player_deathmatch");
  246. +        if (lastspawn != world)
  247. +            return lastspawn;
  248.      }
  249.  
  250.      if (serverflags)
  251. @@ -481,6 +562,9 @@
  252.      local    entity spot;
  253.  
  254.      spot = SelectSpawnPoint ();
  255. +//ZOID: Minimize chance of telefragging someone, from Johannes Plass
  256. +//(plass@dipmza.physik.uni-mainz.de) ServerModules package
  257. +    spot = TelefragSelectSpawnPoint(spot);
  258.  
  259.      self.classname = "player";
  260.      self.health = 100;
  261. @@ -498,6 +582,12 @@
  262.      self.invincible_finished = 0;
  263.      self.effects = 0;
  264.      self.invincible_time = 0;
  265. +    self.staydeadtime = 0;
  266. +    self.regen_time = 0;
  267. +    self.rune_notice_time = 0;
  268. +
  269. +    // Flamethrower - just to be sure
  270. +    self.onfire = FALSE;
  271.  
  272.      DecodeLevelParms ();
  273.      
  274. @@ -537,6 +627,40 @@
  275.      }
  276.  
  277.      spawn_tdeath (self.origin, self);
  278. +
  279. +// *********************************************************************
  280. +// **                                          **
  281. +// ** M U L T I S K I N  1.1  (start)                                  **
  282. +// **                                      **
  283. +// ***********************************************************************
  284. +
  285. +    if (teamplay == 0) {
  286. +        if (self.skin == 0) centerprint(self, "Mr. Quake himself!"); else
  287. +        if (self.skin == 1) centerprint(self, "No time to play with yourself here!"); else
  288. +        if (self.skin == 2) centerprint(self, "You're one pretty toad!"); else
  289. +        if (self.skin == 3) centerprint(self, "Wow Stormtrooper, you're though!"); else
  290. +        if (self.skin == 4) centerprint(self, "Hi Max, looking yellow/blue today!"); else
  291. +        if (self.skin == 5) centerprint(self, "You are back!"); else
  292. +        if (self.skin == 6) centerprint(self, "Judge Dredd! Let's restore some order!"); else
  293. +        if (self.skin == 7) centerprint(self, "Camo! Can't see you, where are you!"); else
  294. +        if (self.skin == 8) centerprint(self, "Okay Captain Picard, make it so!"); else
  295. +        if (self.skin == 9) centerprint(self, "Whizz whizz.. Wizzard!"); else
  296. +        if (self.skin == 10) centerprint(self,"I'm the Predator, you're the prey!"); else
  297. +        if (self.skin == 11) centerprint(self,"Welcome Skeleton, looking good!"); else
  298. +        if (self.skin == 12) centerprint(self,"Wan-Fu, whoever you are :)"); else
  299. +        if (self.skin == 13) centerprint(self,"Oh no, it's Henry Rollins!"); else
  300. +        if (self.skin == 14) centerprint(self,"Ooh no, it's She.. eh.. He-Man"); else
  301. +        if (self.skin == 15) centerprint(self,"If it isn't Boba, go get Han Solo!"); else
  302. +        if (self.skin == 16) centerprint(self,"It's SUPERMAN!"); else
  303. +        if (self.skin == 17) centerprint(self,"Protect the innocent, uphold your law"); else
  304. +        if (self.skin == 18) centerprint(self,"Why is that symbol on your suit?");
  305. +    }
  306. +
  307. +// *************************************************************************
  308. +// **                                          **
  309. +// ** M U L T I S K I N  1.1  (end)                                       **
  310. +// **                                      **
  311. +// *************************************************************************
  312.  };
  313.  
  314.  
  315. @@ -565,6 +689,8 @@
  316.  };
  317.  
  318.  
  319. +void() SpawnRunes;
  320. +
  321.  /*
  322.  saved out by quaked in region mode
  323.  */
  324. @@ -577,6 +703,22 @@
  325.  */
  326.  void() info_player_deathmatch =
  327.  {
  328. +    local entity rspawn;
  329. +
  330. +    if (deathmatch) {
  331. +        // spawn the runes
  332. +        rspawn = spawn();
  333. +        rspawn.nextthink = time + 0.1;
  334. +        rspawn.think = SpawnRunes;
  335. +    }
  336. +};
  337. +
  338. +void() info_player_team1 =
  339. +{
  340. +};
  341. +
  342. +void() info_player_team2 =
  343. +{
  344.  };
  345.  
  346.  /*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24)
  347. @@ -634,16 +776,21 @@
  348.      }
  349.      else
  350.      {
  351. +//ZOID: RandomLevel is called.  Note that RandomLevel handles Capture
  352. +//levels as well.
  353. +        o = spawn();
  354. +        o.map = RandomLevel(mapname);
  355. +
  356.          // find a trigger changelevel
  357. -        o = find(world, classname, "trigger_changelevel");
  358. +//        o = find(world, classname, "trigger_changelevel");
  359.  
  360.          // go back to start if no trigger_changelevel
  361. -        if (!o)
  362. -        {
  363. -            mapname = "start";
  364. -            o = spawn();
  365. -            o.map = mapname;
  366. -        }
  367. +//        if (!o)
  368. +//        {
  369. +//            mapname = "start";
  370. +//            o = spawn();
  371. +//            o.map = mapname;
  372. +//        }
  373.      }
  374.  
  375.      nextmap = o.map;
  376. @@ -654,6 +801,78 @@
  377.          o.think = execute_changelevel;
  378.          o.nextthink = time + 0.1;
  379.      }
  380. +
  381. +};
  382. +
  383. +// Return a new random level, that doesn't match old
  384. +string(string old) RandomLevel =
  385. +{
  386. +local float r;
  387. +
  388. +    r = random();
  389. +    if (teamplay & TEAM_CAPTURE_FLAG) {
  390. +        // capture levels
  391. +        if (old == "e1m1") return "e1m2";
  392. +        if (old == "e1m2") return "e1m3";
  393. +        if (old == "e1m3") return "e1m4";
  394. +        if (old == "e1m4") return "e1m5";
  395. +        if (old == "e1m5") return "e1m6";
  396. +        if (old == "e1m6") return "e1m8";
  397. +        if (old == "e1m8") return "e2m1";
  398. +        if (old == "e2m1") return "e2m2";
  399. +        if (old == "e2m2") return "e2m3";
  400. +        if (old == "e2m3") return "e2m5";
  401. +        if (old == "e2m5") return "e4m3";
  402. +        return "e1m1";
  403. +    }
  404. +    if (r > 0.8) {
  405. +        r = random() * 7;
  406. +        if ((r >= 6) && (old != "e1m1")) return ("e1m1"); // e1m1: Slipgate Complex -- by John Romero
  407. +        if ((r >= 5) && (old != "e1m2")) return ("e1m2"); // e1m2: Castle of the Damned -- by Tim Willits
  408. +        if ((r >= 4) && (old != "e1m3")) return ("e1m3"); // e1m3: The Necropolis -- by Tim Willits
  409. +        if ((r >= 3) && (old != "e1m4")) return ("e1m4"); // e1m4: The Grisly Grotto -- by Tim Willits
  410. +        if ((r >= 2) && (old != "e1m5")) return ("e1m5"); // e1m5: Gloom Keep -- by Tim Willits
  411. +        if ((r >= 1) && (old != "e1m6")) return ("e1m6"); // e1m6: The Door To Chthon -- by American McGee
  412. +// e1m7: The House of Chthon -- removed because of lag problems
  413. +        return ("e1m8"); // e1m8: Ziggurat Vertigo --by American McGee
  414. +    } else if (r > 0.6) {
  415. +        r = random() * 6;
  416. +        if ((r >= 5) && (old != "e2m1")) return ("e2m1"); // e2m1: The Installation -- by John Romero
  417. +        if ((r >= 4) && (old != "e2m2")) return ("e2m2"); // e2m2: Ogre Citadel -- by John Romero
  418. +        if ((r >= 3) && (old != "e2m3")) return ("e2m3"); // e2m3: Crypt of Decay -- by John Romero
  419. +        if ((r >= 2) && (old != "e2m4")) return ("e2m4"); // e2m4: The Ebon Fortress  -- by John Romero
  420. +        if ((r >= 1) && (old != "e2m5")) return ("e2m5"); // e2m5: The Wizard's Manse -- by John Romero
  421. +// e2m6: The Dismal Oubliette -- removed because it sucks for dm
  422. +        return ("e2m7"); // e2m7: Underearth --by Tim Willits
  423. +    } else if (r > 0.4) {
  424. +        r = random() * 6;
  425. +        if ((r >= 5) && (old != "e3m1")) return ("e3m1"); // e3m1: Termination Central -- by John Romero
  426. +        if ((r >= 4) && (old != "e3m2")) return ("e3m2"); // e3m2: The Vaults of Zin -- by American McGee
  427. +        if ((r >= 3) && (old != "e3m3")) return ("e3m3"); // e3m3: The Tomb of Terror -- by American McGee
  428. +// e3m4 (Satan's Dark Delight) removed because it sucks for dm
  429. +        if ((r >= 2) && (old != "e3m5")) return ("e3m5"); // e3m5: Wind Tunnels --by Tim Willits
  430. +        if ((r >= 1) && (old != "e3m6")) return ("e3m6"); // e3m6: Chambers of Torment -- by American McGee & Tim Willits
  431. +        return ("e3m7"); // e3m7: The Haunted Halls -- by American McGee
  432. +    } else if (r > 0.2) {
  433. +        r = random() * 8;
  434. +        if ((r >= 7) && (old != "e4m1")) return ("e4m1"); // e4m1: The Sewage System -- by Tim Willits
  435. +        if ((r >= 6) && (old != "e4m2")) return ("e4m2"); // e4m2: The Tower of Despair --by Sandy Petersen
  436. +        if ((r >= 5) && (old != "e4m3")) return ("e4m3"); // e4m3: The Elder God Shrine --by Sandy Petersen
  437. +        if ((r >= 4) && (old != "e4m4")) return ("e4m4"); // e4m4: The Palace of Hate --by Sandy Petersen
  438. +        if ((r >= 3) && (old != "e4m5")) return ("e4m5"); // e4m5: Hell's Atrium --by Sandy Petersen
  439. +        if ((r >= 2) && (old != "e4m6")) return ("e4m6"); // e4m6: The Pain Maze --by Sandy Petersen
  440. +        if ((r >= 1) && (old != "e4m7")) return ("e4m7"); // e4m7: Azure Agony --by Sandy Petersen
  441. +        return ("e4m8"); // e4m8: The Nameless City -- by Sandy Petersen
  442. +    } else {
  443. +        r = random() * 6;
  444. +        if ((r >= 5) && (old != "dm1")) return ("dm1"); // dm1: Place of Two Deaths --by Tim Willits
  445. +        if ((r >= 4) && (old != "dm2")) return ("dm2"); // dm2: Claustrophobopolis --by American McGee
  446. +        if ((r >= 3) && (old != "dm3")) return ("dm3"); // dm3: The Abandoned Base --by John Romero
  447. +        if ((r >= 2) && (old != "dm4")) return ("dm4"); // dm4: The Bad Place --by American McGee
  448. +        if ((r >= 1) && (old != "dm5")) return ("dm5"); // dm5: The Cistern --by Tim Willits
  449. +        return ("dm6"); // dm6: The Dark Zone --by Tim Willits
  450. +    }
  451. +    return("start");
  452.  };
  453.  
  454.  /*
  455. @@ -886,6 +1105,7 @@
  456.              return;
  457.          }
  458.      }
  459. +
  460.  };
  461.  
  462.  
  463. @@ -906,15 +1126,29 @@
  464.          IntermissionThink ();    // otherwise a button could be missed between
  465.          return;                    // the think tics
  466.      }
  467. +    if (self.staydeadtime && self.staydeadtime > time)
  468. +        return;// wait a bit before respawn
  469. +
  470. +// *TEAMPLAY*
  471. +    if (coop && TEAM_STRICT_COOP)
  472. +        return;
  473.  
  474.      if (self.view_ofs == '0 0 0')
  475.          return;        // intermission or finale
  476.  
  477.      makevectors (self.v_angle);        // is this still used
  478.  
  479. +    if (self.motd_time && self.motd_time < time)
  480. +        MOTD();
  481. +
  482.      CheckRules ();
  483.      WaterMove ();
  484.  
  485. +// *TEAMPLAY*
  486. +// TeamCheckLock performs all necessary teamlock checking, and performs all
  487. +// actions needed.
  488. +    TeamCheckLock();
  489. +
  490.      if (self.waterlevel == 2)
  491.          CheckWaterJump ();
  492.  
  493. @@ -938,7 +1172,18 @@
  494.      if (time < self.pausetime)
  495.          self.velocity = '0 0 0';
  496.  
  497. -    if(time > self.attack_finished && self.currentammo == 0 && self.weapon != IT_AXE)
  498. +// RUNE: If player has rune of elder magic (4), regeneration
  499. +    if (self.player_flag & ITEM_RUNE4_FLAG) {
  500. +        if (self.health < 100 && self.regen_time < time) {
  501. +            self.health = self.health + 2;
  502. +            self.regen_time = time + 0.5;
  503. +            RegenerationSound();
  504. +        }
  505. +    }
  506. +// RUNE
  507. +
  508. +    if(time > self.attack_finished && self.currentammo == 0 && 
  509. +        self.weapon != IT_AXE && self.weapon != IT_HOOK)
  510.      {
  511.          self.weapon = W_BestWeapon ();
  512.          W_SetCurrentAmmo ();
  513. @@ -1026,10 +1271,12 @@
  514.              self.invincible_time = 0;
  515.              self.invincible_finished = 0;
  516.          }
  517. -        if (self.invincible_finished > time)
  518. -            self.effects = self.effects | EF_DIMLIGHT;
  519. -        else
  520. -            self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  521. +// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
  522. +// client.qc:CheckDimLight
  523. +//        if (self.invincible_finished > time)
  524. +//            self.effects = self.effects | EF_DIMLIGHT;
  525. +//        else
  526. +//            self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  527.      }
  528.  
  529.  // super damage
  530. @@ -1061,10 +1308,12 @@
  531.              self.super_damage_finished = 0;
  532.              self.super_time = 0;
  533.          }
  534. -        if (self.super_damage_finished > time)
  535. -            self.effects = self.effects | EF_DIMLIGHT;
  536. -        else
  537. -            self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  538. +// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
  539. +// client.qc:CheckDimLight
  540. +//        if (self.super_damage_finished > time)
  541. +//            self.effects = self.effects | EF_DIMLIGHT;
  542. +//        else
  543. +//            self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  544.      }    
  545.  
  546.  // suit    
  547. @@ -1098,6 +1347,8 @@
  548.          }
  549.      }    
  550.  
  551. +    // Check to see about DIMLIGHT effects
  552. +    CheckDimLight();
  553.  };
  554.  
  555.  
  556. @@ -1113,6 +1364,8 @@
  557.      local    float    mspeed, aspeed;
  558.      local    float    r;
  559.  
  560. +        local   string  num;
  561. +
  562.      if (self.view_ofs == '0 0 0')
  563.          return;        // intermission or finale
  564.      if (self.deadflag)
  565. @@ -1143,6 +1396,7 @@
  566.          self.jump_flag = self.velocity_z;
  567.  
  568.      CheckPowerups ();
  569. +
  570.  };
  571.  
  572.  
  573. @@ -1158,6 +1412,26 @@
  574.      bprint (self.netname);
  575.      bprint (" entered the game\n");
  576.      
  577. +    dprint("Client ");
  578. +    dprint(self.netname);
  579. +    dprint(" added\n");
  580. +
  581. +    self.motd_time = time + 3;
  582. +    self.motd_count = 0;
  583. +
  584. +    self.suicide_count = 0;
  585. +    self.killed = 0;
  586. +    
  587. +// *TEAMPLAY*
  588. +     // If this is our first connection, parm10 is < 0
  589. +     // Set lastteam negative.
  590. +     if(parm10 < 0) {
  591. +         self.lastteam = -50;
  592. +        TeamCheckLock();
  593. +        self.lastteam = self.lastteam + 128; // force a stuff cmd in think
  594. +    }
  595. +
  596.  // a client connecting during an intermission can cause problems
  597.      if (intermission_running)
  598.          ExitIntermission ();
  599. @@ -1184,9 +1458,43 @@
  600.      bprint (ftos(self.frags));
  601.      bprint (" frags\n");
  602.      sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
  603. +    DropRune();
  604. +    TeamCaptureDropFlag();
  605.      set_suicide_frame ();
  606.  };
  607.  
  608. +void(entity targ, entity attacker, string what) LogPlayerDMDeath =
  609. +{
  610. +    dprint("death ");
  611. +    dprint(targ.netname);
  612. +    dprint(" by ");
  613. +    dprint(attacker.netname);
  614. +    dprint(" ");
  615. +    dprint(what);
  616. +    dprint(" ");
  617. +    dprint(ftos(targ.frags));
  618. +    dprint(" ");
  619. +    dprint(ftos(attacker.frags));
  620. +    dprint("\n");
  621. +};
  622. +
  623. +void (entity targ, string what) LogPlayerDeath =
  624. +{
  625. +    dprint("death ");
  626. +    dprint(targ.netname);
  627. +    dprint(" ");
  628. +    dprint(what);
  629. +    dprint(" ");
  630. +    dprint(ftos(targ.frags));
  631. +    dprint("\n");
  632. +};
  633. +
  634. +// *TEAMPLAY*
  635. +// Prototypes
  636. +
  637. +float(entity targ, entity attacker) TeamFragPenalty;
  638. +void(entity targ, entity attacker) TeamDeathPenalty;
  639. +
  640.  /*
  641.  ===========
  642.  ClientObituary
  643. @@ -1197,7 +1505,7 @@
  644.  void(entity targ, entity attacker) ClientObituary =
  645.  {
  646.      local    float rnum;
  647. -    local    string deathstring, deathstring2;
  648. +    local    string deathstring, deathstring2, what, s;
  649.      rnum = random();
  650.  
  651.      if (targ.classname == "player")
  652. @@ -1210,6 +1518,7 @@
  653.              bprint ("\n");
  654.  
  655.              attacker.owner.frags = attacker.owner.frags + 1;
  656. +            LogPlayerDMDeath(targ, attacker.owner, "telefrag");
  657.              return;
  658.          }
  659.  
  660. @@ -1220,6 +1529,7 @@
  661.              bprint ("'s telefrag\n");
  662.  
  663.              targ.frags = targ.frags - 1;
  664. +            LogPlayerDeath(targ, "telefrag");
  665.              return;
  666.          }
  667.  
  668. @@ -1234,12 +1544,20 @@
  669.                  if (targ.weapon == 64 && targ.waterlevel > 1)
  670.                  {
  671.                      bprint (" discharges into the water.\n");
  672. +                    LogPlayerDeath(targ, "discharge");
  673.                      return;
  674.                  }
  675. -                if (targ.weapon == IT_GRENADE_LAUNCHER)
  676. +                if (targ.weapon == IT_GRENADE_LAUNCHER) {
  677.                      bprint (" tries to put the pin back in\n");
  678. -                else
  679. +                    LogPlayerDeath(targ, "grenade");
  680. +                } else if (targ.team != targ.lastteam) {
  681. +                    //ZOID: try if player was gibbed for changing teams
  682. +                    bprint (" changed teams\n");
  683. +                    LogPlayerDeath(targ, "teamchange");
  684. +                } else {
  685.                      bprint (" becomes bored with life\n");
  686. +                    LogPlayerDeath(targ, "rocket");
  687. +                }
  688.                  return;
  689.              }
  690.              else if ( (teamplay == 2) && (targ.team > 0)&&(targ.team == attacker.team) )
  691. @@ -1259,33 +1577,66 @@
  692.              }
  693.              else
  694.              {
  695. +// *TEAMPLAY*
  696. +// TeamFragPenalty returns true if the attacker gets a frag penalty for
  697. +// killing this target.  It also deducts frags as needed.
  698. +                if (!TeamFragPenalty(targ, attacker))
  699. +                    //ZOID: If in capture mode, do we count regular frags?
  700. +                    if ((targ.player_flag & ITEM_ENEMY_FLAG) &&
  701. +                        targ.team != attacker.team) {
  702. +                        //ZOID: fragged enemy flag carrier
  703. +                        attacker.frags = attacker.frags + 
  704. +                            TEAM_CAPTURE_FRAG_CARRIER_BONUS;
  705. +                        sprint(attacker, "Enemy carrier killed: ");
  706. +                        s = ftos(TEAM_CAPTURE_FRAG_CARRIER_BONUS);
  707. +                        sprint(attacker, s);
  708. +                        sprint(attacker, " point bonus\n");
  709. +                    } else
  710.                  attacker.frags = attacker.frags + 1;
  711.  
  712. +// *TEAMPLAY*
  713. +// TeamDeathPenalty kills the attacker if necessary and adjusts frags to
  714. +// offset the one frag penalty for dying.
  715. +                TeamDeathPenalty(targ, attacker);
  716. +
  717.                  rnum = attacker.weapon;
  718.                  if (rnum == IT_AXE)
  719.                  {
  720.                      deathstring = " was ax-murdered by ";
  721.                      deathstring2 = "\n";
  722. +                    what = "axe";
  723. +                }
  724. +                if (rnum == IT_HOOK) {
  725. +                    if (random() < 0.5)
  726. +                        deathstring = " was disembowled by ";
  727. +                    else
  728. +                        deathstring = " was hooked by ";
  729. +                    deathstring2 = "\n";
  730. +                    what = "hook";
  731.                  }
  732.                  if (rnum == IT_SHOTGUN)
  733.                  {
  734.                      deathstring = " chewed on ";
  735.                      deathstring2 = "'s boomstick\n";
  736. +                    what = "shotgun";
  737.                  }
  738.                  if (rnum == IT_SUPER_SHOTGUN)
  739.                  {
  740.                      deathstring = " ate 2 loads of ";
  741.                      deathstring2 = "'s buckshot\n";
  742. +                    what = "supershotgun";
  743.                  }
  744.                  if (rnum == IT_NAILGUN)
  745.                  {
  746.                      deathstring = " was nailed by ";
  747.                      deathstring2 = "\n";
  748. +                    what = "nailgun";
  749.                  }
  750.                  if (rnum == IT_SUPER_NAILGUN)
  751.                  {
  752.                      deathstring = " was punctured by ";
  753.                      deathstring2 = "\n";
  754. +                    what = "supernailgun";
  755.                  }
  756.                  if (rnum == IT_GRENADE_LAUNCHER)
  757.                  {
  758. @@ -1296,6 +1647,13 @@
  759.                          deathstring = " was gibbed by ";
  760.                          deathstring2 = "'s grenade\n";
  761.                      }
  762. +                    what = "grenade";
  763. +                }
  764. +                if (rnum == IT_FLAMETHROWER)
  765. +                {
  766. +                    deathstring = " is invited to ";
  767. +                    deathstring2 = "'s barbeque\n";
  768. +                    what = "flamethrower";
  769.                  }
  770.                  if (rnum == IT_ROCKET_LAUNCHER)
  771.                  {
  772. @@ -1306,6 +1664,7 @@
  773.                          deathstring = " was gibbed by ";
  774.                          deathstring2 = "'s rocket\n" ;
  775.                      }
  776. +                    what = "rocket";
  777.                  }
  778.                  if (rnum == IT_LIGHTNING)
  779.                  {
  780. @@ -1314,11 +1673,13 @@
  781.                          deathstring2 = "'s discharge\n";
  782.                      else
  783.                          deathstring2 = "'s shaft\n";
  784. +                    what = "lightning";
  785.                  }
  786.                  bprint (targ.netname);
  787.                  bprint (deathstring);
  788.                  bprint (attacker.netname);
  789.                  bprint (deathstring2);
  790. +                LogPlayerDMDeath(targ, attacker, what);
  791.              }
  792.              return;
  793.          }
  794. @@ -1330,38 +1691,55 @@
  795.              // killed by a montser?
  796.              if (attacker.flags & FL_MONSTER)
  797.              {
  798. -                if (attacker.classname == "monster_army")
  799. +                if (attacker.classname == "monster_army") {
  800.                      bprint (" was shot by a Grunt\n");
  801. -                if (attacker.classname == "monster_demon1")
  802. +                    LogPlayerDeath(targ, "grunt");
  803. +                } else if (attacker.classname == "monster_demon1") {
  804.                      bprint (" was eviscerated by a Fiend\n");
  805. -                if (attacker.classname == "monster_dog")
  806. +                    LogPlayerDeath(targ, "fiend");
  807. +                } else if (attacker.classname == "monster_dog") {
  808.                      bprint (" was mauled by a Rottweiler\n");
  809. -                if (attacker.classname == "monster_dragon")
  810. +                    LogPlayerDeath(targ, "dog");
  811. +                } else if (attacker.classname == "monster_dragon") {
  812.                      bprint (" was fried by a Dragon\n");
  813. -                if (attacker.classname == "monster_enforcer")
  814. +                    LogPlayerDeath(targ, "dragon");
  815. +                } else if (attacker.classname == "monster_enforcer") {
  816.                      bprint (" was blasted by an Enforcer\n");
  817. -                if (attacker.classname == "monster_fish")
  818. +                    LogPlayerDeath(targ, "enforcer");
  819. +                } else if (attacker.classname == "monster_fish") {
  820.                      bprint (" was fed to the Rotfish\n");
  821. -                if (attacker.classname == "monster_hell_knight")
  822. +                    LogPlayerDeath(targ, "fish");
  823. +                } else if (attacker.classname == "monster_hell_knight") {
  824.                      bprint (" was slain by a Death Knight\n");
  825. -                if (attacker.classname == "monster_knight")
  826. +                    LogPlayerDeath(targ, "deathknight");
  827. +                } else if (attacker.classname == "monster_knight") {
  828.                      bprint (" was slashed by a Knight\n");
  829. -                if (attacker.classname == "monster_ogre")
  830. +                    LogPlayerDeath(targ, "knight");
  831. +                } else if (attacker.classname == "monster_ogre") {
  832.                      bprint (" was destroyed by an Ogre\n");
  833. -                if (attacker.classname == "monster_oldone")
  834. +                    LogPlayerDeath(targ, "ogre");
  835. +                } else if (attacker.classname == "monster_oldone") {
  836.                      bprint (" became one with Shub-Niggurath\n");
  837. -                if (attacker.classname == "monster_shalrath")
  838. +                    LogPlayerDeath(targ, "shub");
  839. +                } else if (attacker.classname == "monster_shalrath") {
  840.                      bprint (" was exploded by a Vore\n");
  841. -                if (attacker.classname == "monster_shambler")
  842. +                    LogPlayerDeath(targ, "vore");
  843. +                } else if (attacker.classname == "monster_shambler") {
  844.                      bprint (" was smashed by a Shambler\n");
  845. -                if (attacker.classname == "monster_tarbaby")
  846. +                    LogPlayerDeath(targ, "shambler");
  847. +                } else if (attacker.classname == "monster_tarbaby") {
  848.                      bprint (" was slimed by a Spawn\n");
  849. -                if (attacker.classname == "monster_vomit")
  850. +                    LogPlayerDeath(targ, "spawn");
  851. +                } else if (attacker.classname == "monster_vomit") {
  852.                      bprint (" was vomited on by a Vomitus\n");
  853. -                if (attacker.classname == "monster_wizard")
  854. +                    LogPlayerDeath(targ, "vomitus");
  855. +                } else if (attacker.classname == "monster_wizard") {
  856.                      bprint (" was scragged by a Scrag\n");
  857. -                if (attacker.classname == "monster_zombie")
  858. +                    LogPlayerDeath(targ, "scrag");
  859. +                } else if (attacker.classname == "monster_zombie") {
  860.                      bprint (" joins the Zombies\n");
  861. +                    LogPlayerDeath(targ, "zombie");
  862. +                }
  863.  
  864.                  return;
  865.              }
  866. @@ -1370,26 +1748,31 @@
  867.              if (attacker.classname == "explo_box")
  868.              {
  869.                  bprint (" blew up\n");
  870. +                LogPlayerDeath(targ, "explosion");
  871.                  return;
  872.              }
  873.              if (attacker.solid == SOLID_BSP && attacker != world)
  874.              {    
  875.                  bprint (" was squished\n");
  876. +                LogPlayerDeath(targ, "squished");
  877.                  return;
  878.              }
  879.              if (attacker.classname == "trap_shooter" || attacker.classname == "trap_spikeshooter")
  880.              {
  881.                  bprint (" was spiked\n");
  882. +                LogPlayerDeath(targ, "spiked");
  883.                  return;
  884.              }
  885.              if (attacker.classname == "fireball")
  886.              {
  887.                  bprint (" ate a lavaball\n");
  888. +                LogPlayerDeath(targ, "fireball");
  889.                  return;
  890.              }
  891.              if (attacker.classname == "trigger_changelevel")
  892.              {
  893.                  bprint (" tried to leave\n");
  894. +                LogPlayerDeath(targ, "noexit");
  895.                  return;
  896.              }
  897.  
  898. @@ -1401,6 +1784,7 @@
  899.                      bprint (" sleeps with the fishes\n");
  900.                  else
  901.                      bprint (" sucks it down\n");
  902. +                LogPlayerDeath(targ, "drowned");
  903.                  return;
  904.              }
  905.              else if (rnum == -4)
  906. @@ -1409,6 +1793,7 @@
  907.                      bprint (" gulped a load of slime\n");
  908.                  else
  909.                      bprint (" can't exist on slime alone\n");
  910. +                LogPlayerDeath(targ, "slimed");
  911.                  return;
  912.              }
  913.              else if (rnum == -5)
  914. @@ -1416,12 +1801,14 @@
  915.                  if (targ.health < -15)
  916.                  {
  917.                      bprint (" burst into flames\n");
  918. +                    LogPlayerDeath(targ, "melted");
  919.                      return;
  920.                  }
  921.                  if (random() < 0.5)
  922.                      bprint (" turned into hot slag\n");
  923.                  else
  924.                      bprint (" visits the Volcano God\n");
  925. +                LogPlayerDeath(targ, "melted");
  926.                  return;
  927.              }
  928.  
  929. @@ -1430,10 +1817,12 @@
  930.              {
  931.                  targ.deathtype = "";
  932.                  bprint (" fell to his death\n");
  933. +                LogPlayerDeath(targ, "falling");
  934.                  return;
  935.              }
  936.  
  937.              // hell if I know; he's just dead!!!
  938. +            LogPlayerDeath(targ, "died");
  939.              bprint (" died\n");
  940.          }
  941.      }
  942. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/combat.qc src/combat.qc
  943. --- v106qc/combat.qc    Thu Sep 26 11:15:38 1996
  944. +++ src/combat.qc    Wed Oct  9 21:12:18 1996
  945. @@ -65,6 +65,7 @@
  946.  
  947.      if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
  948.      {    // doors, triggers, etc
  949. +
  950.          self.th_die ();
  951.          self = oself;
  952.          return;
  953. @@ -91,6 +92,12 @@
  954.  };
  955.  
  956.  
  957. +// *TEAMPLAY*
  958. +// Prototypes
  959. +
  960. +float(entity targ, entity inflictor, entity attacker, float damage) TeamArmorDam;
  961. +float(entity targ, entity inflictor, entity attacker, float damage) TeamHealthDam;
  962. +
  963.  /*
  964.  ============
  965.  T_Damage
  966. @@ -115,10 +122,29 @@
  967.  // check for quad damage powerup on the attacker
  968.      if (attacker.super_damage_finished > time)
  969.          damage = damage * 4;
  970. +// RUNE: check for double damage for rune of Black Magic powerup
  971. +    if (attacker.player_flag & ITEM_RUNE2_FLAG)
  972. +        damage = damage * 2;
  973. +// check if target has rune of Earth Magic (half damage)
  974. +    if (targ.player_flag & ITEM_RUNE1_FLAG) {
  975. +        damage = damage / 2;
  976. +        if (targ.invincible_sound < time) {
  977. +            sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  978. +            targ.invincible_sound = time + 2;
  979. +        }
  980. +    }
  981. +// RUNE
  982.  
  983.  // save damage based on the target's armor level
  984.  
  985. +// *TEAMPLAY*
  986. +// TeamArmorDam returns true iff the attacker can damage the target's armor
  987. +
  988. +        if (TeamArmorDam(targ, inflictor, attacker, damage))
  989.      save = ceil(targ.armortype*damage);
  990. +        else
  991. +                save = 0;
  992. +
  993.      if (save >= targ.armorvalue)
  994.      {
  995.          save = targ.armorvalue;
  996. @@ -163,6 +189,13 @@
  997.  // team play damage avoidance
  998.      if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) )
  999.          return;
  1000. +        
  1001. +// *TEAMPLAY*
  1002. +// TeamHealthDam will return true if the attacker can damage the target's
  1003. +// health
  1004. +
  1005. +        if (!TeamHealthDam(targ, inflictor, attacker, damage))
  1006. +                return;
  1007.          
  1008.  // do the damage
  1009.      targ.health = targ.health - take;
  1010. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/defs.qc src/defs.qc
  1011. --- v106qc/defs.qc    Thu Sep 26 11:15:38 1996
  1012. +++ src/defs.qc    Sun Oct  6 15:01:38 1996
  1013. @@ -290,7 +290,7 @@
  1014.  float    IT_GRENADE_LAUNCHER        = 16;
  1015.  float    IT_ROCKET_LAUNCHER        = 32;
  1016.  float    IT_LIGHTNING            = 64;
  1017. -float    IT_EXTRA_WEAPON            = 128;
  1018. +float   IT_FLAMETHROWER                 = 128;
  1019.  
  1020.  float    IT_SHELLS                = 256;
  1021.  float    IT_NAILS                = 512;
  1022. @@ -309,6 +309,7 @@
  1023.  float    IT_INVULNERABILITY        = 1048576;
  1024.  float    IT_SUIT                    = 2097152;
  1025.  float    IT_QUAD                    = 4194304;
  1026. +float    IT_HOOK                    = 8388608;
  1027.  
  1028.  // point content values
  1029.  
  1030. @@ -409,6 +410,11 @@
  1031.  
  1032.  float        skill;
  1033.  
  1034. +entity    runespawn;
  1035. +float    runespawned;
  1036. +float    capturespawned;
  1037. +float    teamscored;        // non-zero if teams scored
  1038. +
  1039.  //================================================
  1040.  
  1041.  //
  1042. @@ -457,10 +463,16 @@
  1043.  //
  1044.  // player only fields
  1045.  //
  1046. +
  1047. +// *TEAMPLAY*
  1048. +
  1049. +.float          lastteam;       // The last team this player was a member of.
  1050. +
  1051.  .float        walkframe;
  1052.  
  1053.  .float         attack_finished;
  1054.  .float        pain_finished;
  1055. +.float        hook_out;
  1056.  
  1057.  .float        invincible_finished;
  1058.  .float        invisible_finished;
  1059. @@ -470,6 +482,8 @@
  1060.  .float        invincible_time, invincible_sound;
  1061.  .float        invisible_time, invisible_sound;
  1062.  .float        super_time, super_sound;
  1063. +.float        regeneration_sound;//RUNE: Elder Magic
  1064. +.float        haste_sound;//RUNE: Hell Magic
  1065.  .float        rad_time;
  1066.  .float        fly_sound;
  1067.  
  1068. @@ -483,6 +497,26 @@
  1069.  .float        air_finished;    // when time > air_finished, start drowning
  1070.  .float        bubble_count;    // keeps track of the number of bubbles
  1071.  .string        deathtype;        // keeps track of how the player died
  1072. +.float         player_flag;    // misc flags (skins, etc.)
  1073. +.float        staydeadtime;    // how long we should stay dead
  1074. +.float        regen_time;        // time to next regen
  1075. +.float        rune_notice_time;    // last time we notified about multi-runes
  1076. +
  1077. +// ZOID: Runes
  1078. +float        ITEM_RUNE1_FLAG        = 1;
  1079. +float        ITEM_RUNE2_FLAG        = 2;
  1080. +float        ITEM_RUNE3_FLAG        = 4;
  1081. +float        ITEM_RUNE4_FLAG        = 8;
  1082. +float        ITEM_RUNE_MASK        = 15;
  1083. +
  1084. +// ZOID: Capture the flag
  1085. +float        ITEM_ENEMY_FLAG        = 16;
  1086. +
  1087. +.float        motd_time;
  1088. +.float        motd_count;
  1089. +
  1090. +.float        suicide_count;
  1091. +.float        killed;            // have we been killed yet
  1092.  
  1093.  //
  1094.  // object stuff
  1095. @@ -690,4 +724,9 @@
  1096.  
  1097.  float(entity targ, entity inflictor) CanDamage;
  1098.  
  1099. +
  1100. +// Flamethrower
  1101. +
  1102. +.float  onfire;//Flag... set if the entity is on fire
  1103. +.entity  firewood;// Pointer to an entity that the flame will burn.
  1104.  
  1105. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/doors.qc src/doors.qc
  1106. --- v106qc/doors.qc    Thu Sep 26 11:15:38 1996
  1107. +++ src/doors.qc    Sun Oct  6 15:01:38 1996
  1108. @@ -560,6 +560,7 @@
  1109.  float SECRET_1ST_DOWN = 4;        // 1st move is down from arrow
  1110.  float SECRET_NO_SHOOT = 8;        // only opened by trigger
  1111.  float SECRET_YES_SHOOT = 16;    // shootable even if targeted
  1112. +float SECRET_NEVER = 32;        // lock it shut
  1113.  
  1114.  
  1115.  void () fd_secret_use =
  1116. @@ -576,6 +577,9 @@
  1117.  
  1118.      SUB_UseTargets();                // fire all targets / killtargets
  1119.      
  1120. +    if (self.spawnflags & SECRET_NEVER)
  1121. +        return; // it never opens
  1122. +    
  1123.      if (!(self.spawnflags & SECRET_NO_SHOOT))
  1124.      {
  1125.          self.th_pain = SUB_Null;
  1126. @@ -758,6 +762,7 @@
  1127.      self.solid = SOLID_BSP;
  1128.      self.movetype = MOVETYPE_PUSH;
  1129.      self.classname = "door";
  1130. +
  1131.      setmodel (self, self.model);
  1132.      setorigin (self, self.origin);    
  1133.      
  1134. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/flame.qc src/flame.qc
  1135. --- v106qc/flame.qc    Wed Dec 31 19:00:00 1969
  1136. +++ src/flame.qc    Sun Oct  6 15:01:38 1996
  1137. @@ -0,0 +1,212 @@
  1138. +/*
  1139. +============================================================================
  1140. +
  1141. +Quake Flamethrower 1.0
  1142. +
  1143. +Another groovy patch from Quake Command - http://www.nuc.net/quake
  1144. +
  1145. +QC Code By : Steve Bond         wedge@nuc.net
  1146. +
  1147. +Apologies in advance... I was unable to comment this as well as I'd have
  1148. +liked to. (I used some weird variable names - hope they don't cause problems.
  1149. +
  1150. +============================================================================
  1151. +*/
  1152. +
  1153. +// Internal declaration
  1154. +        void (vector fireorg) SpawnTouchFlame;
  1155. +        void () BurnThem;
  1156. +
  1157. +// Player.qc declaration
  1158. +        void () DeathBubblesSpawn;
  1159. +
  1160. +
  1161. +
  1162. +// Slightly varied version of DEATHBUBBLES
  1163. +void(float num_bubbles, vector bub_origin) NewBubbles =
  1164. +{
  1165. +local entity    bubble_spawner;
  1166. +    
  1167. +    bubble_spawner = spawn();
  1168. +        setorigin (bubble_spawner, bub_origin);
  1169. +    bubble_spawner.movetype = MOVETYPE_NONE;
  1170. +    bubble_spawner.solid = SOLID_NOT;
  1171. +    bubble_spawner.nextthink = time + 0.1;
  1172. +
  1173. +        if (self.classname == "player")
  1174. +                bubble_spawner.owner = self;
  1175. +        else
  1176. +                bubble_spawner.owner = self.firewood;
  1177. +
  1178. +        bubble_spawner.think = DeathBubblesSpawn;
  1179. +    bubble_spawner.bubble_count = num_bubbles;
  1180. +    return;
  1181. +};
  1182. +
  1183. +
  1184. +/*
  1185. +===============
  1186. +Burn Them!
  1187. +===============
  1188. +*/
  1189. +void () BurnThem =
  1190. +{
  1191. +        // CHECK FOR WATER *FIRST*
  1192. +        if (self.firewood.waterlevel >= 1)
  1193. +        {
  1194. +                NewBubbles(6,self.firewood.origin);
  1195. +                self.firewood.onfire = FALSE;
  1196. +// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
  1197. +// client.qc:CheckDimLight
  1198. +//              self.firewood.effects = self.firewood.effects - EF_DIMLIGHT;
  1199. +                remove(self);
  1200. +                return;
  1201. +        }
  1202. +        if (self.firewood.onfire < time) {
  1203. +                self.firewood.onfire = FALSE;
  1204. +// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
  1205. +// client.qc:CheckDimLight
  1206. +//              self.firewood.effects = self.firewood.effects - EF_DIMLIGHT;
  1207. +                remove(self);
  1208. +                return;
  1209. +        }
  1210. +
  1211. +        else if (self.firewood.health > 0)
  1212. +        {
  1213. +                SpawnTouchFlame(self.firewood.origin);
  1214. +                T_Damage (self.firewood, self, self.owner, 1);
  1215. +                self.nextthink = time + 0.25;
  1216. +        }
  1217. +        else if (self.firewood.health <= 0) {
  1218. +// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
  1219. +// client.qc:CheckDimLight
  1220. +//              self.firewood.effects = self.firewood.effects - EF_DIMLIGHT;
  1221. +                self.firewood.onfire = FALSE;
  1222. +                remove(self);
  1223. +                return;
  1224. +        }
  1225. +};
  1226. +
  1227. +
  1228. +/*
  1229. +================
  1230. +SpawnTouchFlame
  1231. +================
  1232. +*/
  1233. +
  1234. +void (vector fireorg) SpawnTouchFlame =
  1235. +{
  1236. +        local entity    flame;
  1237. +        local   float   rn;
  1238. +
  1239. +        flame = spawn ();
  1240. +        flame.owner = self;
  1241. +        flame.movetype = MOVETYPE_FLYMISSILE;
  1242. +        flame.velocity = '0 0 75';
  1243. +        flame.solid = SOLID_NOT;
  1244. +        flame.classname = "fire";
  1245. +        flame.origin = fireorg;
  1246. +        flame.think = s_explode1;
  1247. +        flame.nextthink = time;
  1248. +        setmodel (flame, "progs/s_explod.spr");
  1249. +        setsize (flame, '0 0 0', '0 0 0');            
  1250. +};
  1251. +
  1252. +/*
  1253. +================
  1254. +FlameTouch
  1255. +================
  1256. +*/
  1257. +void () FlameTouch =
  1258. +{
  1259. +        local   float   rn;
  1260. +
  1261. +        if (other == self.owner)
  1262. +                return;
  1263. +
  1264. +        if (other.takedamage)
  1265. +        {
  1266. +                rn = random();
  1267. +                // 20% chance
  1268. +                if (rn <= 0.2 && !other.onfire)
  1269. +                {
  1270. +                        // Fire stays with whatever it hits
  1271. +                        if (other.classname == "player")
  1272. +                        {
  1273. +                                centerprint(other,"You are on fire! Find WATER!\n");
  1274. +                                stuffcmd (other,"bf\n");
  1275. +                        }
  1276. +                        other.onfire = time + 5; // burn for five secs
  1277. +                        self.firewood = other;
  1278. +                        self.think = BurnThem;
  1279. +                        self.nextthink = time;
  1280. +                        self.solid = SOLID_NOT;
  1281. +                        setmodel (self,"");
  1282. +// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
  1283. +// client.qc:CheckDimLight
  1284. +//                        other.effects = other.effects | EF_DIMLIGHT;
  1285. +                }
  1286. +                else
  1287. +                {
  1288. +                        SpawnTouchFlame(other.origin);
  1289. +                        T_Damage (other, self, self.owner, 10 );
  1290. +                        remove (self);
  1291. +                }
  1292. +        }
  1293. +        else if (other.classname == "worldspawn")
  1294. +        {
  1295. +                self.velocity = '0 0 0';
  1296. +        }
  1297. +};
  1298. +
  1299. +/*
  1300. +================
  1301. +W_FireFlame
  1302. +================
  1303. +*/
  1304. +void() W_FireFlame =
  1305. +{
  1306. +        local   entity flame;
  1307. +        local   float rn;
  1308. +
  1309. +        if (self.waterlevel > 2)
  1310. +        {
  1311. +                makevectors (self.v_angle);
  1312. +                NewBubbles(2, self.origin+v_forward*64);
  1313. +
  1314. +                rn = random();
  1315. +                if (rn < 0.5)
  1316. +                        sound (self, CHAN_WEAPON, "misc/water1.wav", 1, ATTN_NORM);
  1317. +                else
  1318. +                        sound (self, CHAN_WEAPON, "misc/water2.wav", 1, ATTN_NORM);
  1319. +
  1320. +                return;
  1321. +        }
  1322. +
  1323. +        // Take away a shell
  1324. +        self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  1325. +
  1326. +        sound (self, CHAN_WEAPON, "hknight/hit.wav", 1, ATTN_NORM);
  1327. +
  1328. +        flame = spawn ();
  1329. +        flame.owner = self;
  1330. +        flame.movetype = MOVETYPE_FLYMISSILE;
  1331. +        flame.solid = SOLID_BBOX;
  1332. +        flame.classname = "fire";
  1333. +        
  1334. +// set flame speed    
  1335. +
  1336. +    makevectors (self.v_angle);
  1337. +
  1338. +                flame.velocity = aim(self, 10000);
  1339. +                flame.velocity = flame.velocity * 300;
  1340. +
  1341. +        flame.touch = FlameTouch;
  1342. +    
  1343. +        flame.think = s_explode1;
  1344. +        flame.nextthink = time + 0.15;
  1345. +
  1346. +        setmodel (flame, "progs/s_explod.spr");
  1347. +        setsize (flame, '0 0 0', '0 0 0');            
  1348. +        setorigin (flame, self.origin + v_forward * 16 + '0 0 16');
  1349. +};
  1350. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/hook.qc src/hook.qc
  1351. --- v106qc/hook.qc    Wed Dec 31 19:00:00 1969
  1352. +++ src/hook.qc    Sat Oct 12 21:23:41 1996
  1353. @@ -0,0 +1,228 @@
  1354. +
  1355. +/************\
  1356. +* BreakChain *
  1357. +\************/
  1358. +
  1359. +void (entity Head) BreakChain =
  1360. +{
  1361. +        local entity link;
  1362. +
  1363. +        link = Head.goalentity;
  1364. +        while (link != world)
  1365. +        {
  1366. +                Head = link.goalentity;
  1367. +                remove (link);
  1368. +                link = Head;
  1369. +        }
  1370. +};
  1371. +
  1372. +/*********\
  1373. +* LinkPos *
  1374. +\*********/
  1375. +
  1376. +void () LinkPos =
  1377. +{
  1378. +        makevectors (self.enemy.angles);
  1379. +        setorigin (self, self.owner.origin + ( ( ( self.enemy.origin + 
  1380. +                (v_up * 16 * (!self.enemy.button2)) + (v_forward * 16) ) - self.owner.origin ) *
  1381. +                ( self.weapon ) ) );
  1382. +        self.nextthink = time + 0.1;
  1383. +};
  1384. +
  1385. +/***********\
  1386. +* MakeChain *
  1387. +\***********/
  1388. +
  1389. +entity (entity head, entity tail, float num) MakeChain =
  1390. +{
  1391. +        local entity link, prevlink;
  1392. +        local float linknum;
  1393. +
  1394. +        linknum = num;
  1395. +        num = num + 1;
  1396. +        prevlink = world;
  1397. +        while (linknum > 0)
  1398. +        {
  1399. +                link = spawn();
  1400. +
  1401. +                link.goalentity = prevlink;
  1402. +                prevlink = link;
  1403. +
  1404. +                link.owner = head;
  1405. +                link.enemy = tail;
  1406. +                link.weapon = linknum / num;
  1407. +                link.movetype = MOVETYPE_NOCLIP;
  1408. +                link.solid = SOLID_NOT;
  1409. +                link.angles_z = 51 * linknum;
  1410. +                link.angles_y = 41 * linknum;
  1411. +                link.angles_x = 31 * linknum;
  1412. +                link.avelocity = '310 410 510';
  1413. +                setmodel (link, "progs/s_spike.mdl");
  1414. +                setsize (link, '0 0 0', '0 0 0');
  1415. +                makevectors (tail.angles);
  1416. +                setorigin (link, head.origin + ( ( ( tail.origin 
  1417. +                        + (v_up * 16 * (!tail.button2)) + ( v_forward * 16 ) ) - head.origin )
  1418. +                        * ( link.weapon ) ) );
  1419. +                link.nextthink = time + 0.1;
  1420. +                link.think = LinkPos;
  1421. +                linknum = linknum - 1;
  1422. +        }
  1423. +        return link;
  1424. +};
  1425. +
  1426. +
  1427. +/************\
  1428. +* HookVanish *
  1429. +\************/
  1430. +
  1431. +void () HookVanish =
  1432. +{
  1433. +        self.owner.hook_out = FALSE;
  1434. +/*
  1435. +        if (self.enemy.classname == "player")
  1436. +                self.enemy.attack_finished = time + 0.1;
  1437. +*/
  1438. +        BreakChain (self);
  1439. +        remove (self);
  1440. +};
  1441. +
  1442. +/**********\
  1443. +* HookPull *
  1444. +\**********/
  1445. +
  1446. +void () HookPull =
  1447. +{
  1448. +        local vector vel, spray;
  1449. +        local float v;
  1450. +
  1451. +    if ((!self.owner.button0 && (self.owner.weapon == IT_HOOK)) ||
  1452. +        (self.owner.teleport_time > time ) || self.owner.deadflag ) {
  1453. +        HookVanish();
  1454. +        return;
  1455. +    } else {
  1456. +         if (self.enemy.takedamage) {
  1457. +            // don't hurt teammates
  1458. +            if (self.enemy.classname != "player" || !teamplay ||
  1459. +                self.enemy.team != self.owner.team) {
  1460. +                sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM);
  1461. +                T_Damage (self.enemy, self, self.owner, 1);
  1462. +                makevectors (self.v_angle);
  1463. +                spray_x = 100 * crandom();
  1464. +                spray_y = 100 * crandom();
  1465. +                spray_z = 100 * crandom() + 50;
  1466. +                SpawnBlood (self.origin, spray, 20);
  1467. +            }
  1468. +            if (self.enemy.solid == SOLID_SLIDEBOX) {
  1469. +                    self.velocity = '0 0 0';
  1470. +                    setorigin (self, self.enemy.origin +
  1471. +                            self.enemy.mins +
  1472. +                            (self.enemy.size * 0.5));
  1473. +            } else {
  1474. +                    self.velocity = self.enemy.velocity;
  1475. +            }
  1476. +        } else {
  1477. +                self.velocity = self.enemy.velocity;
  1478. +        }
  1479. +        if (self.enemy.solid == SOLID_NOT) {
  1480. +                HookVanish();
  1481. +                return;
  1482. +        }
  1483. +        makevectors (self.owner.angles);
  1484. +        vel = self.origin - ( self.owner.origin + (v_up * 16 *
  1485. +                (!self.owner.button2)) + (v_forward * 16));
  1486. +        v = vlen (vel);
  1487. +        if (v <= 100)
  1488. +                vel = normalize(vel) * v * 10;  
  1489. +        if ( v > 100 )
  1490. +                vel = normalize(vel) * 1000;  
  1491. +        self.owner.velocity = vel;
  1492. +        self.nextthink = time + 0.1;
  1493. +    }
  1494. +};
  1495. +
  1496. +/**************\
  1497. +* T_ChainTouch *
  1498. +\**************/
  1499. +
  1500. +void() T_ChainTouch =
  1501. +{
  1502. +        if (other == self.owner)
  1503. +                return;         // don't attach to owner
  1504. +
  1505. +    if (pointcontents(self.origin) == CONTENT_SKY) {
  1506. +                HookVanish();
  1507. +                return;
  1508. +    }
  1509. +
  1510. +    if (other.takedamage) {
  1511. +        // don't damage teammates
  1512. +        if (other.classname != "player" || !teamplay ||
  1513. +            other.team != self.owner.team) {
  1514. +            if (other.classname == "player")
  1515. +                other.axhitme = 1; // make axe noise
  1516. +            else
  1517. +                sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  1518. +            T_Damage (other, self, self.owner, 10 );
  1519. +            SpawnBlood (self.origin, self.velocity, 10);
  1520. +        } else
  1521. +            sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  1522. +    } else {
  1523. +        sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  1524. +        self.avelocity = '0 0 0';
  1525. +    }
  1526. +                
  1527. +        if (!self.owner.button0) {
  1528. +                HookVanish();
  1529. +                return;
  1530. +        } else {
  1531. +                if (other.solid == SOLID_SLIDEBOX) {
  1532. +                        setorigin (self, other.origin + other.mins +
  1533. +                                (other.size * 0.5));
  1534. +                        self.velocity = '0 0 0';
  1535. +                } else {
  1536. +                        self.velocity = other.velocity;
  1537. +                }
  1538. +                self.weapon = other.nextthink - time;
  1539. +                self.enemy = other;
  1540. +                self.nextthink = time + 0.1;
  1541. +                self.think = HookPull;
  1542. +                self.touch = SUB_Null;
  1543. +        }
  1544. +};
  1545. +
  1546. +/*************\
  1547. +* W_FireChain *
  1548. +\*************/
  1549. +
  1550. +void() W_FireChain =
  1551. +{
  1552. +        local entity hook;
  1553. +
  1554. +        self.hook_out = TRUE;
  1555. +        hook = spawn ();
  1556. +        hook.owner = self;
  1557. +        hook.movetype = MOVETYPE_FLY;
  1558. +        hook.solid = SOLID_BBOX;
  1559. +        
  1560. +// set hook speed 
  1561. +
  1562. +        makevectors (self.v_angle);
  1563. +        hook.velocity = aim(self, 1000);
  1564. +        hook.velocity = hook.velocity * 1000;
  1565. +        hook.angles = vectoangles(hook.velocity);
  1566. +        hook.avelocity = '0 0 -500';
  1567. +    
  1568. +        hook.touch = T_ChainTouch;
  1569. +    
  1570. +// set hook sound
  1571. +        hook.nextthink = time + 5;
  1572. +        hook.think = HookVanish;
  1573. +
  1574. +        setmodel (hook, "progs/v_spike.mdl");
  1575. +        setsize (hook, '0 0 0', '0 0 0');     
  1576. +        setorigin (hook, self.origin + (v_forward*16) + '0 0 16' );
  1577. +
  1578. +        sound (self, CHAN_WEAPON, "hknight/hit.wav", 1, ATTN_NORM);    
  1579. +
  1580. +        hook.goalentity = MakeChain (hook, self, 2);
  1581. +};
  1582. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/items.qc src/items.qc
  1583. --- v106qc/items.qc    Thu Sep 26 11:15:38 1996
  1584. +++ src/items.qc    Mon Oct 14 01:46:27 1996
  1585. @@ -168,10 +168,13 @@
  1586.              return;
  1587.      }
  1588.      
  1589. +// ZOID--remove uncessary msgs
  1590. +    if (!deathmatch) {
  1591.      sprint(other, "You receive ");
  1592.      s = ftos(self.healamount);
  1593.      sprint(other, s);
  1594.      sprint(other, " health\n");
  1595. +    }
  1596.      
  1597.  // health touch sound
  1598.      sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1599. @@ -207,8 +210,9 @@
  1600.  {
  1601.      other = self.owner;
  1602.      
  1603. -    if (other.health > other.max_health)
  1604. -    {
  1605. +//ZOID: player doesn't rot if they have Elder Magic rune
  1606. +    if (other.health > other.max_health && 
  1607. +        !(other.player_flag & ITEM_RUNE4_FLAG)) {
  1608.          other.health = other.health - 1;
  1609.          self.nextthink = time + 1;
  1610.          return;
  1611. @@ -275,6 +279,8 @@
  1612.          self.nextthink = time + 20;
  1613.      self.think = SUB_regen;
  1614.  
  1615. +//ZOID--remove unneccessary msgs
  1616. +    if (!deathmatch)
  1617.      sprint(other, "You got armor\n");
  1618.  // armor touch sound
  1619.      sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  1620. @@ -376,6 +382,8 @@
  1621.      local float or, nr;
  1622.  
  1623.  // change self.weapon if desired
  1624. +    if (self.weapon == IT_HOOK && self.button0)
  1625. +        return; // never change if we pulled ourselves to it.
  1626.      or = RankForWeapon (self.weapon);
  1627.      nr = RankForWeapon (new);
  1628.      if ( nr < or )
  1629. @@ -415,6 +423,8 @@
  1630.              return;
  1631.          hadammo = other.ammo_nails;            
  1632.          new = IT_NAILGUN;
  1633. +// *TEAMPLAY*
  1634. +        if ( !( coop && (teamplay & TEAM_DROP_ITEMS) ) )
  1635.          other.ammo_nails = other.ammo_nails + 30;
  1636.      }
  1637.      else if (self.classname == "weapon_supernailgun")
  1638. @@ -423,6 +433,8 @@
  1639.              return;
  1640.          hadammo = other.ammo_rockets;            
  1641.          new = IT_SUPER_NAILGUN;
  1642. +// *TEAMPLAY*
  1643. +        if ( !( coop && (teamplay & TEAM_DROP_ITEMS) ) )
  1644.          other.ammo_nails = other.ammo_nails + 30;
  1645.      }
  1646.      else if (self.classname == "weapon_supershotgun")
  1647. @@ -431,6 +443,8 @@
  1648.              return;
  1649.          hadammo = other.ammo_rockets;            
  1650.          new = IT_SUPER_SHOTGUN;
  1651. +// *TEAMPLAY*
  1652. +        if ( !( coop && (teamplay & TEAM_DROP_ITEMS) ) )
  1653.          other.ammo_shells = other.ammo_shells + 5;
  1654.      }
  1655.      else if (self.classname == "weapon_rocketlauncher")
  1656. @@ -439,6 +453,8 @@
  1657.              return;
  1658.          hadammo = other.ammo_rockets;            
  1659.          new = IT_ROCKET_LAUNCHER;
  1660. +// *TEAMPLAY*
  1661. +        if ( !( coop && (teamplay & TEAM_DROP_ITEMS) ) )
  1662.          other.ammo_rockets = other.ammo_rockets + 5;
  1663.      }
  1664.      else if (self.classname == "weapon_grenadelauncher")
  1665. @@ -446,7 +462,11 @@
  1666.          if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  1667.              return;
  1668.          hadammo = other.ammo_rockets;            
  1669. +// FLAMETHROWER
  1670. +        other.items = other.items | IT_FLAMETHROWER;
  1671.          new = IT_GRENADE_LAUNCHER;
  1672. +// *TEAMPLAY*
  1673. +        if ( !( coop && (teamplay & TEAM_DROP_ITEMS) ) )
  1674.          other.ammo_rockets = other.ammo_rockets + 5;
  1675.      }
  1676.      else if (self.classname == "weapon_lightning")
  1677. @@ -455,14 +475,20 @@
  1678.              return;
  1679.          hadammo = other.ammo_rockets;            
  1680.          new = IT_LIGHTNING;
  1681. +// *TEAMPLAY*
  1682. +        if ( !( coop && (teamplay & TEAM_DROP_ITEMS) ) )
  1683.          other.ammo_cells = other.ammo_cells + 15;
  1684.      }
  1685.      else
  1686.          objerror ("weapon_touch: unknown classname");
  1687.  
  1688. +//ZOID--remove unnessary msgs
  1689. +    if (!deathmatch) {
  1690.      sprint (other, "You got the ");
  1691.      sprint (other, self.netname);
  1692.      sprint (other, "\n");
  1693. +    }
  1694. +
  1695.  // weapon touch sound
  1696.      sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  1697.      stuffcmd (other, "bf\n");
  1698. @@ -645,9 +671,12 @@
  1699.  
  1700.      bound_other_ammo ();
  1701.      
  1702. +//ZOID--remove unnessary msgs
  1703. +    if (!deathmatch) {
  1704.      sprint (other, "You got the ");
  1705.      sprint (other, self.netname);
  1706.      sprint (other, "\n");
  1707. +    }
  1708.  // ammo touch sound
  1709.      sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1710.      stuffcmd (other, "bf\n");
  1711. @@ -1237,6 +1266,9 @@
  1712.          return;
  1713.      if (other.health <= 0)
  1714.          return;
  1715. +    //don't let self pick it up for a sec
  1716. +    if ((other == self.owner) && ( (self.nextthink - time) > 118 ) )
  1717. +        return;
  1718.  
  1719.      acount = 0;
  1720.      sprint (other, "You get ");
  1721. @@ -1339,9 +1371,22 @@
  1722.      item = spawn();
  1723.      item.origin = self.origin - '0 0 24';
  1724.      
  1725. +    // if weapon is flamethrower, change quickly to grenade launcher
  1726. +    if (self.weapon == IT_FLAMETHROWER)
  1727. +        self.weapon = IT_GRENADE_LAUNCHER;
  1728. +
  1729. +    item.items = 0; // none by default
  1730. +
  1731. +//ZOID--axe and hook don't go into backpack
  1732. +    if (self.weapon != IT_HOOK || self.weapon != IT_AXE)
  1733.      item.items = self.weapon;
  1734. -    if (item.items == IT_AXE)
  1735. -        item.netname = "Axe";
  1736. +
  1737. +    // If weapon was grenade launcher, flamethrower goes in backpack too
  1738. +    if (self.weapon == IT_GRENADE_LAUNCHER)
  1739. +        item.items = item.items | IT_FLAMETHROWER;
  1740. +
  1741. +//    if (item.items == IT_AXE)
  1742. +//        item.netname = "Axe";
  1743.      else if (item.items == IT_SHOTGUN)
  1744.          item.netname = "Shotgun";
  1745.      else if (item.items == IT_SUPER_SHOTGUN)
  1746. @@ -1378,3 +1423,237 @@
  1747.      item.nextthink = time + 120;    // remove after 2 minutes
  1748.      item.think = SUB_Remove;
  1749.  };
  1750. +
  1751. +/*----------------------------------------------------------------------
  1752. +  The Rune Game modes
  1753. +
  1754. +  Rune 1 - Earth Magic
  1755. +      resistance
  1756. +  Rune 2 - Black Magic
  1757. +      strength
  1758. +  Rune 3 - Hell Magic
  1759. +      haste
  1760. +  Rune 4 - Elder Magic
  1761. +      regeneration
  1762. +
  1763. + ----------------------------------------------------------------------*/
  1764. +
  1765. +entity() SelectRuneSpawnPoint =
  1766. +{
  1767. +    runespawn = find(runespawn, classname, "info_player_deathmatch");
  1768. +    if (runespawn == world)
  1769. +        runespawn = find (runespawn, classname, "info_player_deathmatch");
  1770. +    if (runespawn == world)
  1771. +        error("no info_player_deathmatch to spawn rune");
  1772. +    return runespawn;
  1773. +};
  1774. +
  1775. +void() RuneTouch =
  1776. +{
  1777. +    local string    s;
  1778. +    local    float    best;
  1779. +    local        entity    stemp;
  1780. +    
  1781. +    if (other.classname != "player")
  1782. +        return;
  1783. +    if (other.health <= 0)
  1784. +        return;
  1785. +    if (other.player_flag & ITEM_RUNE_MASK) {
  1786. +        if (other.rune_notice_time < time) {
  1787. +            centerprint(other, "You already have a rune.\n");
  1788. +            other.rune_notice_time = time + 5;
  1789. +        }
  1790. +        return; // one per customer
  1791. +    }
  1792. +        
  1793. +    other.player_flag = other.player_flag | self.player_flag;
  1794. +
  1795. +    // notification of rune, no nofity in team mode
  1796. +    if (self.player_flag & ITEM_RUNE1_FLAG) {
  1797. +        bprint(other.netname);
  1798. +//        bprint(" got the rune of Earth Magic!\n");
  1799. +        bprint(" got the rune of ┼ß≥⌠Φ ═ßτΘπ!\n");
  1800. +//        centerprint(other, "You got the Earth Magic Rune!\n\nRESISTANCE\n\nYou now take half damage!");
  1801. +        centerprint(other, "You got the ┼ß≥⌠Φ ═ßτΘπ Rune!\n\n╥σ≤Θ≤⌠ßεπσ\n\nYou now take half damage!");
  1802. +    }
  1803. +    if (self.player_flag & ITEM_RUNE2_FLAG) {
  1804. +        bprint(other.netname);
  1805. +//        bprint(" got the rune of Black Magic!\n");
  1806. +        bprint(" got the rune of ┬∞ßπδ ═ßτΘπ!\n");
  1807. +//        centerprint(other, "You got the Black Magic Rune!\n\nSTRENGTH\n\nYou now dish out double damage!");
  1808. +        centerprint(other, "You got the ┬∞ßπδ ═ßτΘπ Rune!\n\n╙⌠≥σετ⌠Φ\n\nYou now dish out double damage!");
  1809. +    }
  1810. +    if (self.player_flag & ITEM_RUNE3_FLAG) {
  1811. +        bprint(other.netname);
  1812. +//        bprint(" got the rune of Hell Magic!\n");
  1813. +        bprint(" got the rune of ╚σ∞∞ ═ßτΘπ!\n");
  1814. +//        centerprint(other, "You got the Hell Magic Rune!\n\nHASTE\n\nYou now fire twice fast!");
  1815. +        centerprint(other, "You got the ╚σ∞∞ ═ßτΘπ Rune!\n\n╚ß≤⌠σ\n\nYou now fire twice fast!");
  1816. +    }
  1817. +    if (self.player_flag & ITEM_RUNE4_FLAG) {
  1818. +        bprint(other.netname);
  1819. +//        bprint(" got the rune of Elder Magic!\n");
  1820. +        bprint(" got the rune of ┼∞Σσ≥ ═ßτΘπ!\n");
  1821. +//        centerprint(other, "You got the Elder Magic Rune!\n\nREGENERATION\n\nYou now regenerate!");
  1822. +        centerprint(other, "You got the ┼∞Σσ≥ ═ßτΘπ Rune!\n\n╥στσεσ≥ß⌠Θ∩ε\n\nYou now regenerate!");
  1823. +    }
  1824. +    
  1825. +    // backpack touch sound
  1826. +    sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1827. +    stuffcmd (other, "bf\n");
  1828. +
  1829. +    remove(self);
  1830. +};
  1831. +
  1832. +void (float flag) Do_DropRune;
  1833. +
  1834. +void() RuneRespawn =
  1835. +{
  1836. +    local entity oself;
  1837. +
  1838. +    oself = self;
  1839. +
  1840. +    // choose random starting points
  1841. +    self = SelectRuneSpawnPoint();
  1842. +    Do_DropRune(oself.player_flag);
  1843. +
  1844. +    remove(oself);
  1845. +};
  1846. +
  1847. +void (float flag) Do_DropRune = 
  1848. +{
  1849. +    local entity    item;
  1850. +
  1851. +    item = spawn();
  1852. +    item.origin = self.origin - '0 0 24';
  1853. +    
  1854. +    item.player_flag = flag;
  1855. +
  1856. +    item.velocity_z = 400;
  1857. +    item.velocity_x = -500 + (random() * 1000);
  1858. +    item.velocity_y = -500 + (random() * 1000);
  1859. +    
  1860. +    item.flags = FL_ITEM;
  1861. +    item.solid = SOLID_TRIGGER;
  1862. +    item.movetype = MOVETYPE_TOSS;
  1863. +    if (flag & ITEM_RUNE1_FLAG)
  1864. +        setmodel (item, "progs/end1.mdl");
  1865. +    else if (flag & ITEM_RUNE2_FLAG)
  1866. +        setmodel (item, "progs/end2.mdl");
  1867. +    else if (flag & ITEM_RUNE3_FLAG)
  1868. +        setmodel (item, "progs/end3.mdl");
  1869. +    else if (flag & ITEM_RUNE4_FLAG)
  1870. +        setmodel (item, "progs/end4.mdl");
  1871. +    setsize (item, '-16 -16 0', '16 16 56');
  1872. +    item.touch = RuneTouch;
  1873. +    
  1874. +    item.nextthink = time + 120; /* if no one touches it in two minutes,
  1875. +        respawn it somewhere else, so inaccessible ones will come 'back' */
  1876. +    item.think = RuneRespawn;
  1877. +};
  1878. +
  1879. +/*
  1880. +===============
  1881. +Droprune
  1882. +self is player
  1883. +===============
  1884. +*/
  1885. +void() DropRune =
  1886. +{
  1887. +    if (self.player_flag & ITEM_RUNE1_FLAG)
  1888. +        Do_DropRune(ITEM_RUNE1_FLAG);
  1889. +    if (self.player_flag & ITEM_RUNE2_FLAG)
  1890. +        Do_DropRune(ITEM_RUNE2_FLAG);
  1891. +    if (self.player_flag & ITEM_RUNE3_FLAG)
  1892. +        Do_DropRune(ITEM_RUNE3_FLAG);
  1893. +    if (self.player_flag & ITEM_RUNE4_FLAG)
  1894. +        Do_DropRune(ITEM_RUNE4_FLAG);
  1895. +    self.player_flag = self.player_flag - (self.player_flag & ITEM_RUNE_MASK);
  1896. +};
  1897. +
  1898. +/*
  1899. +================
  1900. +SpawnRunes
  1901. +spawn all the runes
  1902. +self is the entity that was created for us, we remove it
  1903. +================
  1904. +*/
  1905. +void() SpawnRunes =
  1906. +{
  1907. +    local entity oself;
  1908. +    local float i;
  1909. +
  1910. +    if (runespawned) {
  1911. +        remove(self);
  1912. +        return;
  1913. +    }
  1914. +
  1915. +    oself = self;
  1916. +
  1917. +    // choose random starting points
  1918. +    i = random() * 10;
  1919. +    while (i > 0) {
  1920. +        self = SelectRuneSpawnPoint();
  1921. +        i = i - 1;
  1922. +    }
  1923. +
  1924. +    self = SelectRuneSpawnPoint();
  1925. +    Do_DropRune(ITEM_RUNE1_FLAG);
  1926. +    self = SelectRuneSpawnPoint();
  1927. +    Do_DropRune(ITEM_RUNE2_FLAG);
  1928. +    self = SelectRuneSpawnPoint();
  1929. +    Do_DropRune(ITEM_RUNE3_FLAG);
  1930. +    self = SelectRuneSpawnPoint();
  1931. +    Do_DropRune(ITEM_RUNE4_FLAG);
  1932. +
  1933. +    runespawned = 1;
  1934. +
  1935. +    remove(oself);
  1936. +};
  1937. +
  1938. +// ZOID Capture the flag
  1939. +void() item_flag_team1 =
  1940. +{
  1941. +    if (!deathmatch || !(cvar("teamplay") & TEAM_CAPTURE_FLAG)) {
  1942. +        remove(self);
  1943. +        return;
  1944. +    }
  1945. +
  1946. +    self.team = TEAM_COLOR1 + 1;
  1947. +    self.cnt = 1; // it's at home base
  1948. +    precache_model ("progs/w_g_key.mdl");
  1949. +    setmodel (self, "progs/w_g_key.mdl");
  1950. +    self.touch = TeamCaptureFlagTouch;
  1951. +    self.items = IT_KEY2;
  1952. +    precache_sound ("misc/medkey.wav");
  1953. +    precache_sound ("doors/meduse.wav");
  1954. +    self.noise = "misc/medkey.wav";
  1955. +    setsize(self, '-16 -16 -24', '16 16 32');
  1956. +    // make it glow
  1957. +    self.effects = self.effects | EF_DIMLIGHT;
  1958. +    StartItem();
  1959. +};
  1960. +
  1961. +void() item_flag_team2 =
  1962. +{
  1963. +    if (!deathmatch || !(cvar("teamplay") & TEAM_CAPTURE_FLAG)) {
  1964. +        remove(self);
  1965. +        return;
  1966. +    }
  1967. +
  1968. +    self.team = TEAM_COLOR2 + 1;
  1969. +    self.cnt = 1; // it's at home base
  1970. +    precache_model ("progs/w_s_key.mdl");
  1971. +    setmodel (self, "progs/w_s_key.mdl");
  1972. +    self.touch = TeamCaptureFlagTouch;
  1973. +    self.items = IT_KEY1;
  1974. +    precache_sound ("misc/medkey.wav");
  1975. +    precache_sound ("doors/meduse.wav");
  1976. +    self.noise = "misc/medkey.wav";
  1977. +    setsize(self, '-16 -16 -24', '16 16 32');
  1978. +    // make it glow
  1979. +    self.effects = self.effects | EF_DIMLIGHT;
  1980. +    StartItem();
  1981. +};
  1982. +
  1983. +    
  1984. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/player.qc src/player.qc
  1985. --- v106qc/player.qc    Thu Sep 26 11:15:40 1996
  1986. +++ src/player.qc    Sun Oct  6 15:01:39 1996
  1987. @@ -1,5 +1,8 @@
  1988.  
  1989.  void() bubble_bob;
  1990. +void() W_FireChain;
  1991. +void() player_chain5;
  1992. +void() player_chain4;
  1993.  
  1994.  /*
  1995.  ==============================================================================
  1996. @@ -98,7 +101,7 @@
  1997.          return;
  1998.      }
  1999.  
  2000. -    if (self.weapon == IT_AXE)
  2001. +    if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
  2002.      {
  2003.          if (self.walkframe >= 12)
  2004.              self.walkframe = 0;
  2005. @@ -123,7 +126,7 @@
  2006.          return;
  2007.      }
  2008.  
  2009. -    if (self.weapon == IT_AXE)
  2010. +    if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
  2011.      {
  2012.          if (self.walkframe == 6)
  2013.              self.walkframe = 0;
  2014. @@ -167,6 +170,41 @@
  2015.  void()    player_axed3 =    [$axattd3, player_axed4    ] {self.weaponframe=7;W_FireAxe();};
  2016.  void()    player_axed4 =    [$axattd4, player_run    ] {self.weaponframe=8;};
  2017.  
  2018. +void()  player_chain1=  [$axattd1, player_chain2 ] {self.weaponframe=2;};
  2019. +void()  player_chain2=  [$axattd2, player_chain3 ] {self.weaponframe=3;W_FireChain();};
  2020. +
  2021. +void()  player_chain3=  [$axattd3, player_chain3 ]
  2022. +{
  2023. +        self.weaponframe=3;
  2024. +        if (!self.hook_out)
  2025. +        {
  2026. +                player_chain5();
  2027. +                return;
  2028. +        }
  2029. +        if (vlen(self.velocity) >= 750)
  2030. +        {
  2031. +                player_chain4();
  2032. +                return;
  2033. +        }
  2034. +};
  2035. +
  2036. +void() player_chain4=  [$deathc4, player_chain4 ]
  2037. +{
  2038. +        self.weaponframe=4;
  2039. +        if (!self.hook_out)
  2040. +        {
  2041. +                player_chain5();
  2042. +                return;
  2043. +        }
  2044. +        if (vlen(self.velocity) < 750)
  2045. +        {
  2046. +                player_chain3();
  2047. +                return;
  2048. +        }
  2049. +};
  2050. +
  2051. +void()  player_chain5=  [$axattd4, player_run    ] {self.weaponframe=5;};
  2052. +
  2053.  
  2054.  //============================================================================
  2055.  
  2056. @@ -342,7 +380,7 @@
  2057.      if (self.invisible_finished > time)
  2058.          return;        // eyes don't have pain frames
  2059.  
  2060. -    if (self.weapon == IT_AXE)
  2061. +    if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
  2062.          player_axpain1 ();
  2063.      else
  2064.          player_pain1 ();
  2065. @@ -505,12 +543,14 @@
  2066.  
  2067.      if (damage_attacker.classname == "teledeath")
  2068.      {
  2069. +        self.staydeadtime = time + 2 + (random() * 3);
  2070.          sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
  2071.          return;
  2072.      }
  2073.  
  2074.      if (damage_attacker.classname == "teledeath2")
  2075.      {
  2076. +        self.staydeadtime = time + 3 + (random() * 6);
  2077.          sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
  2078.          return;
  2079.      }
  2080. @@ -532,9 +572,16 @@
  2081.      self.radsuit_finished = 0;
  2082.      self.modelindex = modelindex_player;    // don't use eyes
  2083.  
  2084. -    if (deathmatch || coop)
  2085. +    if (deathmatch || coop) {
  2086.          DropBackpack();
  2087. +        DropRune();
  2088. +        TeamCaptureDropFlag();
  2089. +    }
  2090.      
  2091. +    if (self.killed == 2)
  2092. +        self.killed = 0;
  2093. +    else
  2094. +        self.killed = 1;
  2095.      self.weaponmodel="";
  2096.      self.view_ofs = '0 0 -8';
  2097.      self.deadflag = DEAD_DYING;
  2098. @@ -555,7 +602,7 @@
  2099.      self.angles_x = 0;
  2100.      self.angles_z = 0;
  2101.      
  2102. -    if (self.weapon == IT_AXE)
  2103. +    if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
  2104.      {
  2105.          player_die_ax1 ();
  2106.          return;
  2107. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/progs.src src/progs.src
  2108. --- v106qc/progs.src    Sun Oct  6 16:01:11 1996
  2109. +++ src/progs.src    Mon Oct  7 20:43:03 1996
  2110. @@ -1,12 +1,19 @@
  2111.  progs.dat
  2112.  
  2113.  defs.qc
  2114. +teamplay.qc     // Compile the teamplay file
  2115.  subs.qc
  2116.  fight.qc
  2117.  ai.qc
  2118.  combat.qc
  2119.  items.qc
  2120. +
  2121.  weapons.qc
  2122. +
  2123. +flame.qc
  2124. +
  2125. +telefrag.qc        // from server modules
  2126. +
  2127.  world.qc
  2128.  client.qc
  2129.  player.qc
  2130. @@ -33,3 +40,4 @@
  2131.  shalrath.qc        // registered
  2132.  enforcer.qc        // registered
  2133.  oldone.qc        // registered
  2134. +hook.qc
  2135. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/teamplay.qc src/teamplay.qc
  2136. --- v106qc/teamplay.qc    Wed Dec 31 19:00:00 1969
  2137. +++ src/teamplay.qc    Mon Oct 14 01:51:32 1996
  2138. @@ -0,0 +1,1180 @@
  2139. +/* teamplay.qc
  2140. +
  2141. +   From
  2142. +        The Comlete Enhanced Teamplay
  2143. +
  2144. +   John Spickes -- jspickes@eng.umd.edu
  2145. +
  2146. +    $Id: teamplay.qc 1.17 1996/08/17 16:52:45 jspickes Exp $
  2147. +
  2148. +    $Log: teamplay.qc $
  2149. +    Revision 1.17  1996/08/17 16:52:45  jspickes
  2150. +    Fixed a problem with displaying the current team settings that could cause
  2151. +    the wrong output when teamplay was negative.  Also added code to indicate
  2152. +    when ID's silly teamplay code is being used.
  2153. +
  2154. +    Revision 1.16  1996/08/17 00:41:52  jspickes
  2155. +    Turned off strict coop by default.
  2156. +    Fixed a bug that could have caused strange behavior if TEAM_COLOR* was
  2157. +    set to -2.
  2158. +
  2159. +    Revision 1.15  1996/08/17 00:34:17  jspickes
  2160. +    Added instructions on drop-item use in current settings output.
  2161. +    Fixed a problem that would allow you to drop lots of backpacks with
  2162. +    nothing in them.
  2163. +
  2164. +*/
  2165. +
  2166. +/** Defs **/
  2167. +
  2168. +/** MODIFIABLE CONSTANTS **/
  2169. +
  2170. +float TEAM_DEFAULT_PENALTY =    1;      // Default frag penalty
  2171. +float TEAM_STRICT_COOP =    0;    // Strict Coop
  2172. +
  2173. +// Allowed team colors
  2174. +// -1 indicates no color
  2175. +
  2176. +float TEAM_COLOR1       =       4;
  2177. +float TEAM_COLOR2       =       13;
  2178. +float TEAM_COLOR3       =       -1;
  2179. +float TEAM_COLOR4       =       -1;
  2180. +
  2181. +/** End of MODIFIABLE CONSTANTS **/
  2182. +
  2183. +// Globals
  2184. +
  2185. +entity team1_lastspawn;
  2186. +entity team2_lastspawn;
  2187. +
  2188. +// Teamplay bitfield entries
  2189. +
  2190. +float TEAM_HEALTH_PROTECT =     1;      // No health damage from friendly fire
  2191. +float TEAM_ARMOR_PROTECT =      2;      // No armor damage from friendly fire
  2192. +float TEAM_ATTACKER_DAMAGE =    4;      // Attacker takes damage from hitting teammates
  2193. +float TEAM_FRAG_PENALTY =       8;      // One frag penalty for killing teammate
  2194. +float TEAM_DEATH_PENALTY =      16;     // Die when you kill a teammate.
  2195. +float TEAM_LOCK_COLORS =        32;     // Allow only team colors
  2196. +float TEAM_STATIC_TEAMS =       64;     // Don't allow players to switch teams
  2197. +float TEAM_DROP_ITEMS =     128;    // Allow players to drop packs and 
  2198. +float TEAM_CAPTURE_FLAG =    256;    // Play capture the flag
  2199. +
  2200. +float TEAM_CAPTURE_CAPTURE_BONUS = 12; // what you get for capture
  2201. +float TEAM_CAPTURE_TEAM_BONUS = 12; // what your team gets for capture
  2202. +float TEAM_CAPTURE_RECOVERY_BONUS = 1; // what you get for recovery
  2203. +float TEAM_CAPTURE_FLAG_BONUS = 1; // what you get for picking up enemy flag
  2204. +float TEAM_CAPTURE_FRAG_CARRIER_BONUS = 3; // what you get for fragging
  2205. +    //enemy flag carrier
  2206. +
  2207. +// Prototypes
  2208. +float() W_BestWeapon;
  2209. +void() W_SetCurrentAmmo;
  2210. +void() bound_other_ammo;
  2211. +void(float o, float n) Deathmatch_Weapon;
  2212. +void() BackpackTouch;
  2213. +
  2214. +// Return a name for the color of a team
  2215. +string(float Team) GetTeamColor =
  2216. +{
  2217. +    if(Team == 0) return("Blue");
  2218. +    else if(Team == 1) return("Steel blue");
  2219. +    else if(Team == 2) return("Brown");
  2220. +    else if(Team == 3) return("Baby blue");
  2221. +    else if(Team == 4) return("Green");
  2222. +    else if(Team == 5) return("Red");
  2223. +    else if(Team == 6) return("Olive");
  2224. +    else if(Team == 7) return("Orange");
  2225. +    else if(Team == 8) return("Peech");
  2226. +    else if(Team == 9) return("Purple");
  2227. +    else if(Team == 10) return("Majenta");
  2228. +    else if(Team == 11) return("Grey");
  2229. +    else if(Team == 12) return("Aqua");
  2230. +    else if(Team == 13) return("Yellow");
  2231. +    else if(Team == 14) return("Blue");
  2232. +    return "Unknown";
  2233. +};
  2234. +
  2235. +
  2236. +/*
  2237. +================
  2238. +TeamPrintSettings
  2239. +
  2240. +Print out current teamplay options
  2241. +================
  2242. +*/
  2243. +
  2244. +void() TeamPrintSettings =
  2245. +{
  2246. +    local string s;
  2247. +    
  2248. +    sprint(self,"The following Teamplay options are set:\n");
  2249. +    
  2250. +    if(teamplay < 0)
  2251. +    {
  2252. +        sprint(self, "Frag penalty manually set to ");
  2253. +        s = ftos(teamplay);
  2254. +        sprint(self, s);
  2255. +        sprint(self, "\n");
  2256. +        return;
  2257. +    }
  2258. +    
  2259. +    if(!teamplay) 
  2260. +    {
  2261. +        sprint(self, "None\n");
  2262. +        return;
  2263. +    }
  2264. +    
  2265. +    if(1 == teamplay)
  2266. +    {
  2267. +        sprint(self, "ID's original teamplay 1\n");
  2268. +        return;
  2269. +    }
  2270. +    
  2271. +    if(teamplay & TEAM_HEALTH_PROTECT)
  2272. +        sprint(self, "Health-Protect ");
  2273. +    
  2274. +    if(teamplay & TEAM_ARMOR_PROTECT)
  2275. +        sprint(self, "Armor-Protect ");
  2276. +        
  2277. +    if(teamplay & TEAM_ATTACKER_DAMAGE)
  2278. +        sprint(self, "Mirror-Damage ");
  2279. +        
  2280. +    if(teamplay & TEAM_FRAG_PENALTY)
  2281. +        sprint(self, "Frag-Penalty ");
  2282. +        
  2283. +    if(teamplay & TEAM_DEATH_PENALTY)
  2284. +        sprint(self, "Death-Penalty ");
  2285. +        
  2286. +    if(teamplay & TEAM_LOCK_COLORS)
  2287. +        sprint(self, "Lock-Colors ");
  2288. +        
  2289. +    if(teamplay & TEAM_STATIC_TEAMS)
  2290. +        sprint(self, "Static-Teams ");
  2291. +        
  2292. +    if(teamplay & TEAM_DROP_ITEMS)
  2293. +        sprint(self, "Drop-Items (Backpack Impulse 20, Weapon Impulse 21) ");
  2294. +        
  2295. +    if(teamplay & TEAM_CAPTURE_FLAG)
  2296. +        sprint(self, "Capture-The-Flag ");
  2297. +
  2298. +    sprint(self, "\n");
  2299. +};
  2300. +
  2301. +/*
  2302. +================
  2303. +TeamArmorDam
  2304. +
  2305. +Return TRUE if the target's armor can take damage from this attacker.
  2306. +================
  2307. +*/
  2308. +
  2309. +float(entity targ, entity inflictor, entity attacker, float damage) TeamArmorDam =
  2310. +{
  2311. +        if( teamplay < 0 )
  2312. +                return TRUE;
  2313. +        if( (teamplay & TEAM_ARMOR_PROTECT) && (attacker.team == targ.team) && (attacker != targ) && (targ.team > 0) )
  2314. +        {
  2315. +                // Armor is protected
  2316. +                return FALSE;
  2317. +        }
  2318. +        return TRUE;
  2319. +};
  2320. +
  2321. +/*
  2322. +================
  2323. +TeamHealthDam
  2324. +
  2325. +Return TRUE if the target can take health damage from this attacker.
  2326. +================
  2327. +*/
  2328. +
  2329. +float(entity targ, entity inflictor, entity attacker, float damage) TeamHealthDam =
  2330. +{
  2331. +        if( teamplay < 0 )
  2332. +        {
  2333. +                return TRUE;
  2334. +        }
  2335. +        if( (attacker.team == targ.team) && (attacker != targ) && (targ.team > 0) )
  2336. +        {
  2337. +                // Attacker and target are on the same team.
  2338. +                if( teamplay & TEAM_ATTACKER_DAMAGE )
  2339. +                {
  2340. +                        // Damage applied to teammate.
  2341. +                        T_Damage(attacker, inflictor, attacker, damage);
  2342. +                }
  2343. +                if( teamplay & TEAM_HEALTH_PROTECT )
  2344. +                {
  2345. +                        // Health is protected
  2346. +                        return FALSE;
  2347. +                }
  2348. +        }
  2349. +        return TRUE;
  2350. +};
  2351. +
  2352. +/*
  2353. +================
  2354. +TeamPFrags
  2355. +
  2356. +Return the number of frags we should penalize attacker for killing targ.
  2357. +================
  2358. +*/
  2359. +
  2360. +float(entity targ, entity attacker) TeamPFrags =
  2361. +{
  2362. +        if( teamplay < 0 )
  2363. +                return (-1 * teamplay);
  2364. +        if( (targ.team > 0) && (targ != attacker) && (targ.team == attacker.team) )
  2365. +        {
  2366. +                // targ and attacker are on the same team
  2367. +                if( teamplay < 0 )
  2368. +                {
  2369. +                        // teamplay indicates frag penalty
  2370. +                        return ( -1 * teamplay );
  2371. +                }
  2372. +                if( teamplay & TEAM_FRAG_PENALTY )
  2373. +                {
  2374. +                        // default penalty
  2375. +                        return TEAM_DEFAULT_PENALTY;
  2376. +                }
  2377. +        }
  2378. +        // No frag penalty
  2379. +        return 0;
  2380. +};
  2381. +
  2382. +/*
  2383. +================
  2384. +TeamFragPenalty
  2385. +
  2386. +If attacker should be penalized for killing targ, penalize attacker
  2387. +and return TRUE.
  2388. +================
  2389. +*/
  2390. +
  2391. +float(entity targ, entity attacker) TeamFragPenalty =
  2392. +{
  2393. +        local float f;
  2394. +
  2395. +        f = TeamPFrags(targ, attacker);
  2396. +
  2397. +        if( f )
  2398. +        {
  2399. +                // We should penalize some frags.
  2400. +                attacker.frags = attacker.frags - f;
  2401. +                return TRUE;
  2402. +        }
  2403. +        // No penalty
  2404. +        return FALSE;
  2405. +};
  2406. +
  2407. +/*
  2408. +=================
  2409. +TeamDeathPenalty
  2410. +
  2411. +If attacker should be killed for killing targ, kill attacker and
  2412. +add a frag to offset the one attacker will lose for killing himself.
  2413. +*/
  2414. +
  2415. +void(entity targ, entity attacker) TeamDeathPenalty =
  2416. +{
  2417. +        //Don't kill anyone if teamplay is negative.
  2418. +        if ( teamplay < 0 )
  2419. +                return;
  2420. +
  2421. +        if ( (teamplay & TEAM_DEATH_PENALTY) && (targ.team > 0) && (attacker != targ) && (attacker.team == targ.team) )
  2422. +        {
  2423. +                //We should kill the attacker.
  2424. +                T_Damage(attacker,attacker,attacker,1000);
  2425. +                //Add a frag to offset the self-kill penalty.
  2426. +                attacker.frags = attacker.frags + 1;
  2427. +        }
  2428. +};
  2429. +
  2430. +/*
  2431. +==================
  2432. +TeamColorIsLegal
  2433. +
  2434. +Return TRUE if the indicated color is legal
  2435. +==================
  2436. +*/
  2437. +float(float color) TeamColorIsLegal =
  2438. +{
  2439. +        // All colors are legal if teamplay is negative.
  2440. +        if( teamplay < 0 )
  2441. +                return TRUE;
  2442. +        // All colors are legal if TEAM_LOCK_COLORS is off.
  2443. +        if( !(teamplay & TEAM_LOCK_COLORS) )
  2444. +                return TRUE;
  2445. +        if( (color == TEAM_COLOR1) && (TEAM_COLOR1 >= 0) )
  2446. +                return TRUE;
  2447. +        if( (color == TEAM_COLOR2) && (TEAM_COLOR2 >= 0) )
  2448. +                return TRUE;
  2449. +        if( (color == TEAM_COLOR3) && (TEAM_COLOR3 >= 0) )
  2450. +                return TRUE;
  2451. +        if( (color == TEAM_COLOR4) && (TEAM_COLOR4 >= 0) )
  2452. +                return TRUE;
  2453. +};
  2454. +
  2455. +/*
  2456. +==================
  2457. +TeamCheckTeam
  2458. +
  2459. +Check if the team self is on is legal, and put self in a legal team if not.
  2460. +Return TRUE if the current color is ok, FALSE if we have to set it.
  2461. +==================
  2462. +*/
  2463. +float() TeamCheckTeam =
  2464. +{
  2465. +        local float TEAM1;
  2466. +        local float TEAM2;
  2467. +        local float TEAM3;
  2468. +        local float TEAM4;
  2469. +
  2470. +        local float newcolor;
  2471. +        local float t;
  2472. +
  2473. +        local entity p;
  2474. +
  2475. +        local string n; 
  2476. +
  2477. +
  2478. +        if( self.lastteam >= 0 )
  2479. +        {
  2480. +                if(TeamColorIsLegal(self.team - 1))
  2481. +                        return TRUE;
  2482. +        }
  2483. +
  2484. +        // Assign the player to a team.
  2485. +
  2486. +        // Sum the players on all the teams.
  2487. +
  2488. +        TEAM1 = 0;
  2489. +        TEAM2 = 0;
  2490. +        TEAM3 = 0;
  2491. +        TEAM4 = 0;
  2492. +
  2493. +        p = find (world, classname, "player");
  2494. +
  2495. +        while(p)
  2496. +        {
  2497. +                if( (TEAM_COLOR1 >= 0) && (p.team == (TEAM_COLOR1 +1)) )
  2498. +                        TEAM1 = TEAM1 + 1;
  2499. +                if( (TEAM_COLOR2 >= 0) && (p.team == (TEAM_COLOR2 +1)) )
  2500. +                        TEAM2 = TEAM2 + 1;
  2501. +                if( (TEAM_COLOR3 >= 0) && (p.team == (TEAM_COLOR3 +1)) )
  2502. +                        TEAM3 = TEAM3 + 1;
  2503. +                if( (TEAM_COLOR4 >= 0) && (p.team == (TEAM_COLOR4 +1)) )
  2504. +                        TEAM4 = TEAM4 + 1;
  2505. +
  2506. +                p = find(p, classname, "player");
  2507. +        }
  2508. +
  2509. +        // Find the team with the least players.
  2510. +
  2511. +        newcolor = TEAM_COLOR1;
  2512. +        t = TEAM1;
  2513. +
  2514. +        if ( (TEAM_COLOR2 >= 0) && (TEAM2 < t) )
  2515. +        {
  2516. +                newcolor = TEAM_COLOR2;
  2517. +                t = TEAM2;
  2518. +        }
  2519. +
  2520. +        if ( (TEAM_COLOR3 >= 0) && (TEAM3 < t) )
  2521. +        {
  2522. +                newcolor = TEAM_COLOR3;
  2523. +                t = TEAM3;
  2524. +        }
  2525. +
  2526. +        if ( (TEAM_COLOR4 >= 0) && (TEAM4 < t) )
  2527. +        {
  2528. +                newcolor = TEAM_COLOR4;
  2529. +                t = TEAM4;
  2530. +        }
  2531. +
  2532. +        // Put the player on a the new team.
  2533. +
  2534. +        n = ftos(newcolor);
  2535. +        stuffcmd(self, "color ");
  2536. +        stuffcmd(self, n);
  2537. +        stuffcmd(self, "\n");
  2538. +
  2539. +        sprint(self, "You have been assigned color ");
  2540. +        sprint(self, n);
  2541. +        sprint(self, "\nLegal colors are:");
  2542. +        if(TEAM_COLOR1 >= 0)
  2543. +        {
  2544. +                n = ftos(TEAM_COLOR1);
  2545. +                sprint(self, " ");
  2546. +                sprint(self, n);
  2547. +        }
  2548. +        if(TEAM_COLOR2 >= 0)
  2549. +        {
  2550. +                n = ftos(TEAM_COLOR2);
  2551. +                sprint(self, " ");
  2552. +                sprint(self, n);
  2553. +        }
  2554. +        if(TEAM_COLOR3 >= 0)
  2555. +        {
  2556. +                n = ftos(TEAM_COLOR3);
  2557. +                sprint(self, " ");
  2558. +                sprint(self, n);
  2559. +        }
  2560. +        if(TEAM_COLOR4 >= 0)
  2561. +        {
  2562. +                n = ftos(TEAM_COLOR4);
  2563. +                sprint(self, " ");
  2564. +                sprint(self, n);
  2565. +        }
  2566. +
  2567. +        sprint(self, "\n");
  2568. +
  2569. +        self.lastteam = newcolor + 1;      // Remember what team we're on
  2570. +        self.team = newcolor + 1;
  2571. +        return FALSE;
  2572. +};
  2573. +
  2574. +/*
  2575. +===============
  2576. +TeamCheckLock
  2577. +
  2578. +Check for team changing and perform whatever actions are neccessary.
  2579. +===============
  2580. +*/
  2581. +void() TeamCheckLock =
  2582. +{
  2583. +        local   float   n;
  2584. +        local   string  s;
  2585. +
  2586. +        // Don't do anything if teamplay is negative
  2587. +        if ( teamplay < 0 )
  2588. +                return;
  2589. +
  2590. +        if (self.lastteam >= 128) {
  2591. +            self.lastteam = self.lastteam - 128;
  2592. +            stuffcmd(self, "color ");
  2593. +            n = self.lastteam - 1;
  2594. +            s = ftos(n);
  2595. +            stuffcmd(self, s);
  2596. +            stuffcmd(self, "\n");
  2597. +            return;
  2598. +        }
  2599. +
  2600. +        if ( !TeamColorIsLegal(self.team - 1) && (self.team == self.lastteam) )
  2601. +                self.lastteam = -1;
  2602. +
  2603. +        // Check to see if the player has changed colors
  2604. +        if (self.team != self.lastteam)
  2605. +        {
  2606. +
  2607. +                // Player has changed colors
  2608. +
  2609. +                // If teams are static and we've been on some team already,
  2610. +                // put us back on the team we were on.
  2611. +
  2612. +                if ( (teamplay & TEAM_STATIC_TEAMS) && (self.lastteam >= 0) )
  2613. +                {
  2614. +                        if ( TeamColorIsLegal(self.lastteam - 1) )
  2615. +                        {
  2616. +                                sprint(self, "You cannot change teams.\n");
  2617. +                                stuffcmd(self, "color ");
  2618. +                                n = self.lastteam - 1;
  2619. +                                s = ftos(n);
  2620. +                                stuffcmd(self, s);
  2621. +                                stuffcmd(self, "\n");
  2622. +                                return;
  2623. +                        }
  2624. +                        else
  2625. +                                self.lastteam = -50;
  2626. +                                // If we're on an illegal team, force a change.
  2627. +                }
  2628. +
  2629. +                // If teamlock is turned off, don't do anything more.
  2630. +                if ( !(teamplay & TEAM_LOCK_COLORS) )
  2631. +                {
  2632. +                        if ( teamplay & TEAM_STATIC_TEAMS )
  2633. +                                self.lastteam = self.team;
  2634. +                        return;
  2635. +                }
  2636. +
  2637. +                if(self.lastteam > 0) {
  2638. +                    s = ftos(self.lastteam);
  2639. +                    // case base respawn
  2640. +                    if (self.killed != 1)
  2641. +                        self.killed = 2;
  2642. +                    T_Damage(self,self,self,1000);  // Kill the player
  2643. +                }
  2644. +                self.frags = 0;                 // Zero out frags
  2645. +                if(TeamCheckTeam())
  2646. +                        self.lastteam = self.team;
  2647. +        }
  2648. +};
  2649. +
  2650. +/*
  2651. +=======================
  2652. +TossBackPack
  2653. +
  2654. +Original idea by Vhold
  2655. +Rewritten by John Spickes
  2656. +
  2657. +Toss out a backpack containing some ammo from your current weapon,
  2658. +and any weapons you don't have.
  2659. +=======================
  2660. +*/
  2661. +void() TossBackpack =
  2662. +{
  2663. +    local entity     item;
  2664. +
  2665. +    // If we don't have any ammo, return
  2666. +    if(self.currentammo <= 0)
  2667. +        return;
  2668. +
  2669. +    item = spawn();
  2670. +
  2671. +    // See if you have the Shotgun or Super Shotgun on
  2672. +        if ( (self.weapon == IT_SHOTGUN) || (self.weapon == IT_SUPER_SHOTGUN) )
  2673. +    {
  2674. +        if( self.ammo_shells >= 20 ) {
  2675. +            item.ammo_shells = 20;
  2676. +            self.ammo_shells = self.ammo_shells - 20;
  2677. +        }
  2678. +        else
  2679. +        {
  2680. +            item.ammo_shells = self.ammo_shells;
  2681. +            self.ammo_shells = 0;
  2682. +        }
  2683. +    }        
  2684. +    
  2685. +    // See if you have neither the Shotgun or Super Shotgun
  2686. +        if ( !(self.items & IT_SHOTGUN) && !(self.items & IT_SUPER_SHOTGUN) )
  2687. +    {
  2688. +        if( self.ammo_shells >= 20 ) {
  2689. +            item.ammo_shells = 20;
  2690. +            self.ammo_shells = self.ammo_shells - 20;
  2691. +        }
  2692. +        else
  2693. +        {
  2694. +            item.ammo_shells = self.ammo_shells;
  2695. +            self.ammo_shells = 0;
  2696. +        }
  2697. +    }        
  2698. +    
  2699. +    // See if we are using a nailgun
  2700. +        if ( (self.weapon == IT_NAILGUN) || (self.weapon == IT_SUPER_NAILGUN) )
  2701. +    {
  2702. +        if( self.ammo_nails >= 20 )
  2703. +        {
  2704. +            item.ammo_nails = 20;
  2705. +            self.ammo_nails = self.ammo_nails - 20;
  2706. +        }
  2707. +        else
  2708. +        {
  2709. +            item.ammo_nails = self.ammo_nails;
  2710. +            self.ammo_nails = 0;
  2711. +        }
  2712. +    }    
  2713. +    // Check to see if we have neither nailgun
  2714. +        if ( !(self.items & IT_NAILGUN) && !(self.items & IT_SUPER_NAILGUN) )
  2715. +    {
  2716. +        if( self.ammo_nails >= 20 )
  2717. +        {
  2718. +            item.ammo_nails = 20;
  2719. +            self.ammo_nails = self.ammo_nails - 20;
  2720. +        }
  2721. +        else
  2722. +        {
  2723. +            item.ammo_nails = self.ammo_nails;
  2724. +            self.ammo_nails = 0;
  2725. +        }
  2726. +    }    
  2727. +    
  2728. +    // See if we are using a grenade or rocket launcher
  2729. +        if ( (self.weapon == IT_GRENADE_LAUNCHER) || (self.weapon == IT_ROCKET_LAUNCHER) )
  2730. +    {
  2731. +        if( self.ammo_rockets >= 10 )
  2732. +        {
  2733. +            item.ammo_rockets = 10;
  2734. +            self.ammo_rockets = self.ammo_rockets - 10;
  2735. +        }
  2736. +        else
  2737. +        {
  2738. +            item.ammo_rockets = self.ammo_rockets;
  2739. +            self.ammo_rockets = 0;
  2740. +        }
  2741. +    }
  2742. +    // See if we have neither the Grenade or rocket launcher
  2743. +        if ( !(self.items & IT_GRENADE_LAUNCHER) && !(self.items & IT_ROCKET_LAUNCHER) )
  2744. +    {
  2745. +        if( self.ammo_rockets >= 10 )
  2746. +        {
  2747. +            item.ammo_rockets = 10;
  2748. +            self.ammo_rockets = self.ammo_rockets - 10;
  2749. +        }
  2750. +        else
  2751. +        {
  2752. +            item.ammo_rockets = self.ammo_rockets;
  2753. +            self.ammo_rockets = 0;
  2754. +        }
  2755. +    }
  2756. +
  2757. +    // See if we're using the lightning gun
  2758. +    if ( self.weapon == IT_LIGHTNING )
  2759. +    {    
  2760. +        if( self.ammo_cells >= 20 )
  2761. +        {
  2762. +            item.ammo_cells = 20;
  2763. +            self.ammo_cells = self.ammo_cells - 20;
  2764. +        }
  2765. +        else
  2766. +        {
  2767. +            item.ammo_cells = self.ammo_cells;
  2768. +            self.ammo_cells = 0;
  2769. +        }
  2770. +    }
  2771. +    // see if we don't have the lightning gun
  2772. +        if ( !(self.items & IT_LIGHTNING) )
  2773. +    {    
  2774. +        if( self.ammo_cells >= 20 )
  2775. +        {
  2776. +            item.ammo_cells = 20;
  2777. +            self.ammo_cells = self.ammo_cells - 20;
  2778. +        }
  2779. +        else
  2780. +        {
  2781. +            item.ammo_cells = self.ammo_cells;
  2782. +            self.ammo_cells = 0;
  2783. +        }
  2784. +    }
  2785. +     
  2786. +    item.owner = self;
  2787. +    makevectors(self.v_angle);
  2788. +
  2789. +    setorigin(item, self.origin + '0 0 16');
  2790. +    item.velocity = aim(self, 1000);
  2791. +    item.velocity = item.velocity * 500;
  2792. +    item.flags = FL_ITEM;
  2793. +    item.solid = SOLID_TRIGGER;
  2794. +    item.movetype = MOVETYPE_BOUNCE;
  2795. +
  2796. +    setmodel (item, "progs/backpack.mdl");
  2797. +    setsize(item, '-16 -16 0', '16 16 56');
  2798. +    item.touch = BackpackTouch;
  2799. +    item.nextthink = time + 120;    // remove after 2 minutes
  2800. +    item.think = SUB_Remove;
  2801. +
  2802. +    W_SetCurrentAmmo();
  2803. +
  2804. +};
  2805. +
  2806. +void() Team_weapon_touch =
  2807. +{
  2808. +    local    float    hadammo, best, new, old;
  2809. +    local entity stemp;
  2810. +
  2811. +    if (!(other.flags & FL_CLIENT))
  2812. +        return;
  2813. +    // Don't let the owner pick up his own weapon for a second.
  2814. +    if ( (other == self.owner) && ( (self.nextthink - time) > 119 ) )
  2815. +        return;
  2816. +
  2817. +// if the player was using his best weapon, change up to the new one if better        
  2818. +    stemp = self;
  2819. +    self = other;
  2820. +    best = W_BestWeapon();
  2821. +    self = stemp;
  2822. +
  2823. +    if (self.classname == "weapon_nailgun")
  2824. +    {
  2825. +        hadammo = other.ammo_nails;            
  2826. +        new = IT_NAILGUN;
  2827. +    }
  2828. +    else if (self.classname == "weapon_supernailgun")
  2829. +    {
  2830. +        hadammo = other.ammo_rockets;            
  2831. +        new = IT_SUPER_NAILGUN;
  2832. +    }
  2833. +    else if (self.classname == "weapon_supershotgun")
  2834. +    {
  2835. +        hadammo = other.ammo_rockets;            
  2836. +        new = IT_SUPER_SHOTGUN;
  2837. +    }
  2838. +    else if (self.classname == "weapon_rocketlauncher")
  2839. +    {
  2840. +        hadammo = other.ammo_rockets;            
  2841. +        new = IT_ROCKET_LAUNCHER;
  2842. +    }
  2843. +    else if (self.classname == "weapon_grenadelauncher")
  2844. +    {
  2845. +        hadammo = other.ammo_rockets;            
  2846. +        new = IT_GRENADE_LAUNCHER;
  2847. +    }
  2848. +    else if (self.classname == "weapon_lightning")
  2849. +    {
  2850. +        hadammo = other.ammo_rockets;            
  2851. +        new = IT_LIGHTNING;
  2852. +    }
  2853. +    else
  2854. +        objerror ("Team_weapon_touch: unknown classname");
  2855. +
  2856. +    sprint (other, "You got the ");
  2857. +    sprint (other, self.netname);
  2858. +    sprint (other, "\n");
  2859. +// weapon touch sound
  2860. +    sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  2861. +    stuffcmd (other, "bf\n");
  2862. +
  2863. +    bound_other_ammo ();
  2864. +
  2865. +// change to the weapon
  2866. +    old = other.items;
  2867. +    other.items = other.items | new;
  2868. +    
  2869. +    remove(self);
  2870. +    self = other;
  2871. +
  2872. +    if (!deathmatch)
  2873. +        self.weapon = new;
  2874. +    else
  2875. +        Deathmatch_Weapon (old, new);
  2876. +
  2877. +    W_SetCurrentAmmo();
  2878. +
  2879. +    activator = other;
  2880. +    SUB_UseTargets();                // fire all targets / killtargets
  2881. +};
  2882. +        
  2883. +void() TossWeapon =
  2884. +{
  2885. +    local entity item;
  2886. +    
  2887. +    if((self.weapon == IT_AXE) || (self.weapon == IT_SHOTGUN) ||
  2888. +        (self.weapon == IT_HOOK))
  2889. +        return;
  2890. +        
  2891. +    item = spawn();
  2892. +    item.owner = self;
  2893. +    makevectors(self.v_angle);
  2894. +
  2895. +    setorigin(item, self.origin + '0 0 16');
  2896. +    item.velocity = aim(self, 1000);
  2897. +    item.velocity = item.velocity * 500;
  2898. +    item.flags = FL_ITEM;
  2899. +    item.solid = SOLID_TRIGGER;
  2900. +    item.movetype = MOVETYPE_BOUNCE;
  2901. +    
  2902. +    if(self.weapon == IT_SUPER_SHOTGUN)
  2903. +    {
  2904. +        setmodel (item, "progs/g_shot.mdl");
  2905. +        item.weapon = IT_SUPER_SHOTGUN;
  2906. +        item.netname = "Double-barrelled Shotgun";
  2907. +        item.classname = "weapon_supershotgun";
  2908. +        self.items = self.items - IT_SUPER_SHOTGUN;
  2909. +    }
  2910. +
  2911. +    if( self.weapon == IT_NAILGUN )
  2912. +    {
  2913. +        setmodel (item, "progs/g_nail.mdl");
  2914. +        item.weapon = IT_NAILGUN;
  2915. +        item.netname = "nailgun";
  2916. +        item.classname = "weapon_nailgun";
  2917. +        self.items = self.items - IT_NAILGUN;
  2918. +    }
  2919. +        
  2920. +    if( self.weapon == IT_SUPER_NAILGUN )
  2921. +    {
  2922. +        setmodel (item, "progs/g_nail2.mdl");
  2923. +        item.weapon = IT_SUPER_NAILGUN;
  2924. +        item.netname = "Super Nailgun";
  2925. +        item.classname = "weapon_supernailgun";
  2926. +        self.items = self.items - IT_SUPER_NAILGUN;
  2927. +    }
  2928. +    
  2929. +    if( self.weapon == IT_GRENADE_LAUNCHER || self.weapon == IT_FLAMETHROWER)
  2930. +    {
  2931. +        setmodel (item, "progs/g_rock.mdl");
  2932. +        item.weapon = 3;
  2933. +        item.netname = "Grenade Launcher";
  2934. +        item.classname = "weapon_grenadelauncher";
  2935. +        self.items = self.items - IT_GRENADE_LAUNCHER;
  2936. +    }
  2937. +    
  2938. +    if( self.weapon == IT_ROCKET_LAUNCHER )
  2939. +    {
  2940. +        setmodel (item, "progs/g_rock2.mdl");
  2941. +        item.weapon = 3;
  2942. +        item.netname = "Rocket Launcher";
  2943. +        item.classname = "weapon_rocketlauncher";
  2944. +        self.items = self.items - IT_ROCKET_LAUNCHER;
  2945. +    }
  2946. +    
  2947. +    if( self.weapon == IT_LIGHTNING )
  2948. +    {
  2949. +        setmodel (item, "progs/g_light.mdl");
  2950. +        item.weapon = 3;
  2951. +        item.netname = "Thunderbolt";
  2952. +        item.classname = "weapon_lightning";
  2953. +        self.items = self.items - IT_LIGHTNING;
  2954. +    }
  2955. +    setsize(item, '-16 -16 0', '16 16 56');
  2956. +    item.touch = Team_weapon_touch;
  2957. +    item.think = SUB_Remove;
  2958. +    item.nextthink = time + 120;
  2959. +    
  2960. +    self.weapon = W_BestWeapon();
  2961. +    W_SetCurrentAmmo();
  2962. +};
  2963. +
  2964. +void() SilentKill;
  2965. +void() SUB_regen;
  2966. +
  2967. +void() TeamCaptureRegenFlags =
  2968. +{
  2969. +    local entity f;
  2970. +    
  2971. +    self = find(world, classname, "item_flag_team1");
  2972. +    if (self != world) 
  2973. +        SUB_regen();
  2974. +    self = find(world, classname, "item_flag_team2");
  2975. +    if (self != world) 
  2976. +        SUB_regen();
  2977. +};
  2978. +
  2979. +void() TeamCaptureFlagSanityCheck =
  2980. +{
  2981. +    local entity p;
  2982. +
  2983. +    // Ok, a flag must be in one of three states
  2984. +    // 1. At home base (though we shouldn't be called in that case)
  2985. +    // 2. On enemy player
  2986. +    // 3. A copy is sitting around somewhere, waiting to be picked up
  2987. +
  2988. +    // at home base?
  2989. +    if (self.model != string_null) {
  2990. +        self.think = TeamCaptureFlagSanityCheck;
  2991. +        self.nextthink = time + 30;
  2992. +        return; // its at home, no prob
  2993. +    }
  2994. +    
  2995. +    // on enemy player?
  2996. +    p = find(world, classname, "player");
  2997. +    while (p != world) {
  2998. +        if ((p.team != self.team) && (p.player_flag & ITEM_ENEMY_FLAG)) {
  2999. +            self.think = TeamCaptureFlagSanityCheck;
  3000. +            self.nextthink = time + 30;
  3001. +            return; // enemy player has it
  3002. +        }
  3003. +        p = find(p, classname, "player");
  3004. +    }
  3005. +
  3006. +    // copy sitting around somewhere
  3007. +    p = find(world, classname, "info_dropped_flag");
  3008. +    while (p != world) {
  3009. +        if (p.team == self.team) {
  3010. +            self.think = TeamCaptureFlagSanityCheck;
  3011. +            self.nextthink = time + 30;
  3012. +            return; // its out hanging around
  3013. +        }
  3014. +        p = find(p, classname, "info_dropped_flag");
  3015. +    }
  3016. +    // didn't find it, oh my
  3017. +    // regen this one
  3018. +    SUB_regen();
  3019. +};
  3020. +
  3021. +void() TeamCaptureFlagTouch =
  3022. +{
  3023. +    local entity p, oself;
  3024. +
  3025. +    if (other.classname != "player")
  3026. +        return;
  3027. +    if (other.health <= 0)
  3028. +        return;
  3029. +
  3030. +    if (other.team != other.lastteam)
  3031. +        return; // something is fishy, somebody is playing with colors
  3032. +
  3033. +    if (self.team == other.team) {
  3034. +        // same team, if the flag is *not* at the base, return
  3035. +        // it to base.  we overload the 'cnt' field for this
  3036. +        if (self.cnt) {
  3037. +            // the flag is at home base.  if the player has the enemy
  3038. +            // flag, he's just won!
  3039. +
  3040. +            if (other.player_flag & ITEM_ENEMY_FLAG) {
  3041. +                bprint(other.netname);
  3042. +                if (other.team == TEAM_COLOR1 + 1)
  3043. +                    bprint(" πß≡⌠⌡≥σΣ the ┬╠╒┼ flag!\n"); // blue
  3044. +                else
  3045. +                    bprint(" πß≡⌠⌡≥σΣ the ╥┼─ flag!\n"); // red
  3046. +                other.items = other.items - (other.items & (IT_KEY1 | IT_KEY2));
  3047. +
  3048. +                sound (other, CHAN_VOICE, "doors/meduse.wav", 1, ATTN_NONE);
  3049. +                // other gets another 10 frag bonus
  3050. +                other.frags = other.frags + TEAM_CAPTURE_CAPTURE_BONUS;
  3051. +
  3052. +                // Ok, let's do the player loop, hand out the bonuses
  3053. +                p = find(world, classname, "player");
  3054. +                while (p != world) {
  3055. +                    self = p;
  3056. +                    self.killed = 0;
  3057. +                    if (self.team == other.team && self != other)
  3058. +                        self.frags = self.frags + TEAM_CAPTURE_TEAM_BONUS;
  3059. +                    if (self.team != other.team)
  3060. +                        centerprint(self, "Your flag was captured!\n");
  3061. +                    else if (self.team == other.team)
  3062. +                        centerprint(self, "Your team captured the flag!\n");
  3063. +                    self.player_flag = self.player_flag - (self.player_flag & ITEM_ENEMY_FLAG);
  3064. +// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
  3065. +// client.qc:CheckDimLight
  3066. +//                    self.effects = self.effects - (self.effects & EF_DIMLIGHT);
  3067. +                    
  3068. +                    p = find(p, classname, "player");
  3069. +                }
  3070. +                // respawn flags
  3071. +                TeamCaptureRegenFlags();
  3072. +                return;
  3073. +            }
  3074. +            return; // its at home base already
  3075. +        }    
  3076. +        // hey, its not home.  return it by teleporting it back
  3077. +        bprint(other.netname);
  3078. +        if (other.team == TEAM_COLOR1 + 1)
  3079. +            bprint(" ≥σ⌠⌡≥εσΣ the ╥┼─ flag!\n"); // red
  3080. +        else
  3081. +            bprint(" ≥σ⌠⌡≥εσΣ the ┬╠╒┼ flag!\n"); // blue
  3082. +        other.frags = other.frags + TEAM_CAPTURE_RECOVERY_BONUS;
  3083. +        sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  3084. +        remove(self); // oops it gone
  3085. +        p = find(world, classname, "player");
  3086. +        while (p != world) {
  3087. +            if (p.team != other.team)
  3088. +                centerprint(p, "Enemy flag has been returned to base!\n");
  3089. +            else if (p.team == other.team)
  3090. +                centerprint(p, "Your flag has been returned to base!\n");
  3091. +            p = find(p, classname, "player");
  3092. +        }
  3093. +        if (other.team == TEAM_COLOR1 + 1) {
  3094. +            self = find(world, classname, "item_flag_team1");
  3095. +            if (self != world)  {
  3096. +                self.think = SUB_Null; // its at home, no need to think
  3097. +                SUB_regen();
  3098. +            }
  3099. +        } else { // TEAM_COLOR2
  3100. +            self = find(world, classname, "item_flag_team2");
  3101. +            if (self != world) {
  3102. +                self.think = SUB_Null; // its at home, no need to think
  3103. +                SUB_regen();
  3104. +            }
  3105. +        }
  3106. +        return;
  3107. +    }
  3108. +
  3109. +    // hey, its not our flag, pick it up
  3110. +    bprint(other.netname);
  3111. +    if (other.team == TEAM_COLOR1 + 1)
  3112. +        bprint(" τ∩⌠ the ┬╠╒┼ flag!\n"); // blue
  3113. +    else
  3114. +        bprint(" τ∩⌠ the ╥┼─ flag!\n"); // red
  3115. +    if (TEAM_CAPTURE_FLAG_BONUS)
  3116. +        other.frags = other.frags + TEAM_CAPTURE_FLAG_BONUS;
  3117. +//    centerprint(other, "YOU GOT THE ENEMY FLAG!\n\nRETURN TO BASE!\n");
  3118. +    centerprint(other, "┘╧╒ ╟╧╘ ╘╚┼ ┼╬┼═┘ ╞╠┴╟\n\n╥┼╘╒╥╬ ╘╧ ┬┴╙┼\n");
  3119. +    sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  3120. +
  3121. +    other.player_flag = other.player_flag + ITEM_ENEMY_FLAG;
  3122. +    other.items = other.items | self.items;
  3123. +    // turn on the glow
  3124. +// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
  3125. +// client.qc:CheckDimLight
  3126. +//    other.effects = other.effects | EF_DIMLIGHT;
  3127. +
  3128. +    // make the flag here disappear
  3129. +    if (self.cnt) {
  3130. +        // home base flags stay
  3131. +        self.solid = SOLID_NOT;
  3132. +        self.model = string_null;
  3133. +        // set up sanity check
  3134. +        self.think = TeamCaptureFlagSanityCheck;
  3135. +        self.nextthink = time + 30; // 30 seconds pre check
  3136. +    } else
  3137. +        remove(self); // dropped flags recyclce
  3138. +
  3139. +    p = find(world, classname, "player");
  3140. +    while (p != world) {
  3141. +        if (p != other) {
  3142. +            if (p.team != other.team)
  3143. +                centerprint(p, "Your flag has been taken!\n");
  3144. +            else if (p.team == other.team)
  3145. +                centerprint(p, "Your team has the enemy flag!\n");
  3146. +        }
  3147. +        p = find(p, classname, "player");
  3148. +    }
  3149. +};
  3150. +
  3151. +void() TeamCaptureReturnFlag =
  3152. +{
  3153. +    local entity f, p;
  3154. +
  3155. +    f = world;
  3156. +    if (self.team == TEAM_COLOR1 + 1) {
  3157. +        f = self;
  3158. +        self = find(world, classname, "item_flag_team1");
  3159. +        if (self != world) {
  3160. +            self.think = SUB_Null; // its at home, no need to think
  3161. +            SUB_regen();
  3162. +        }
  3163. +    } else { // TEAM_COLOR2
  3164. +        f = self;
  3165. +        self = find(world, classname, "item_flag_team2");
  3166. +        if (self != world) {
  3167. +            self.think = SUB_Null; // its at home, no need to think
  3168. +            SUB_regen();
  3169. +        }
  3170. +    }
  3171. +    if (f == world)
  3172. +        return;
  3173. +    p = find(world, classname, "player");
  3174. +    while (p != world) {
  3175. +        if (p.team != f.team)
  3176. +            centerprint(p, "Enemy flag has been returned to base!\n");
  3177. +        else if (p.team == f.team)
  3178. +            centerprint(p, "Your flag has been returned to base!\n");
  3179. +        p = find(p, classname, "player");
  3180. +    }
  3181. +    remove(f);
  3182. +};
  3183. +
  3184. +void() TeamCaptureDropFlag =
  3185. +{
  3186. +    local entity item, f;
  3187. +
  3188. +    if (!(self.player_flag & ITEM_ENEMY_FLAG))
  3189. +        return;
  3190. +
  3191. +    self.player_flag = self.player_flag - ITEM_ENEMY_FLAG;
  3192. +
  3193. +    bprint(self.netname);
  3194. +    if (self.lastteam == TEAM_COLOR1 + 1)
  3195. +        bprint(" ∞∩≤⌠ the ┬╠╒┼ flag!\n"); // blue
  3196. +    else
  3197. +        bprint(" ∞∩≤⌠ the ╥┼─ flag!\n"); // red
  3198. +
  3199. +    item = spawn();
  3200. +    item.items = self.items & (IT_KEY1 | IT_KEY2);
  3201. +    item.origin = self.origin - '0 0 24';
  3202. +    item.cnt = 0; // it's NOT at home base
  3203. +    //NOTE! We check lastteam here instead of team--this is because
  3204. +    //in the mode where we change colors, we get killed
  3205. +    if (self.lastteam == TEAM_COLOR1 + 1) {
  3206. +        item.classname = "info_dropped_flag";
  3207. +        item.team = TEAM_COLOR2 + 1;
  3208. +        f = find(world, classname, "item_flag_team2");
  3209. +        if (f != world) {
  3210. +            setmodel(item, f.mdl);
  3211. +            item.noise = f.noise;
  3212. +        } else {
  3213. +            setmodel(item, "progs/lavaball.mdl");
  3214. +            item.noise = "";
  3215. +        }
  3216. +    } else { // TEAM_COLOR2
  3217. +        item.classname = "info_dropped_flag";
  3218. +        item.team = TEAM_COLOR1 + 1;
  3219. +        f = find(world, classname, "item_flag_team1");
  3220. +        if (f != world) {
  3221. +            setmodel(item, f.mdl);
  3222. +            item.noise = f.noise;
  3223. +        } else {
  3224. +            setmodel(item, "progs/lavaball.mdl");
  3225. +            item.noise = "";
  3226. +        }
  3227. +    }
  3228. +    item.velocity_z = 300;
  3229. +    item.velocity_x = 0;
  3230. +    item.velocity_y = 0;
  3231. +    item.touch = TeamCaptureFlagTouch;
  3232. +    item.flags = FL_ITEM;
  3233. +    item.solid = SOLID_TRIGGER;
  3234. +    item.movetype = MOVETYPE_TOSS;
  3235. +    setsize(item, '-16 -16 -24', '16 16 32');
  3236. +    item.effects = item.effects | EF_DIMLIGHT; // make it glow
  3237. +    // return the flag to base if no one picks it up for a while
  3238. +    item.think = TeamCaptureReturnFlag;
  3239. +    item.nextthink = time + 30;
  3240. +};
  3241. +
  3242. +// self is player
  3243. +entity() TeamCaptureSpawn =
  3244. +{
  3245. +    
  3246. +    if (!(teamplay & TEAM_CAPTURE_FLAG))
  3247. +        return world;
  3248. +
  3249. +    if (self.team == TEAM_COLOR1 + 1) {
  3250. +        team1_lastspawn = find(team1_lastspawn, classname, "info_player_team1");
  3251. +        if (team1_lastspawn == world)
  3252. +            team1_lastspawn = find(team1_lastspawn, classname, "info_player_team1");
  3253. +        return team1_lastspawn;
  3254. +    } else { // if (self.team == TEAM_COLOR2 + 1)
  3255. +        team2_lastspawn = find(team2_lastspawn, classname, "info_player_team2");
  3256. +        if (team2_lastspawn == world)
  3257. +            team2_lastspawn = find(team2_lastspawn, classname, "info_player_team2");
  3258. +        return team2_lastspawn;
  3259. +    }
  3260. +    return world;
  3261. +};
  3262. +
  3263. +// ZOID -- total up team scores and set everyone's frag count to the team
  3264. +// total
  3265. +void() TeamScores =
  3266. +{
  3267. +    local float team1, team2, team3, team4;
  3268. +    local entity p;
  3269. +
  3270. +    if (teamscored || !teamplay)
  3271. +        return; // already scored or not in team mode
  3272. +
  3273. +    teamscored = 1;
  3274. +
  3275. +    team1 = 0;
  3276. +    team2 = 0;
  3277. +    team3 = 0;
  3278. +    team4 = 0;
  3279. +
  3280. +dprint("TeamScores()\n");
  3281. +    p = find(world, classname, "player");
  3282. +    while (p != world) {
  3283. +dprint("  Player=");
  3284. +dprint(p.netname);
  3285. +dprint(" Team=");
  3286. +dprint(ftos(p.team));
  3287. +dprint(" Frags=");
  3288. +dprint(ftos(p.frags));
  3289. +dprint("\n");
  3290. +        if (p.team == TEAM_COLOR1 + 1)
  3291. +            team1 = team1 + p.frags;
  3292. +        else if (p.team == TEAM_COLOR2 + 1)
  3293. +            team2 = team2 + p.frags;
  3294. +        else if (p.team == TEAM_COLOR3 + 1)
  3295. +            team3 = team3 + p.frags;
  3296. +        else if (p.team == TEAM_COLOR4 + 1)
  3297. +            team4 = team4 + p.frags;
  3298. +        p = find(p, classname, "player");
  3299. +    }
  3300. +dprint(" Totals: team1=");
  3301. +dprint(ftos(team1));
  3302. +dprint(" team2=");
  3303. +dprint(ftos(team2));
  3304. +dprint("\n");
  3305. +    p = find(world, classname, "player");
  3306. +    while (p != world) {
  3307. +        if (p.team == TEAM_COLOR1 + 1)
  3308. +            p.frags = team1;
  3309. +        else if (p.team == TEAM_COLOR2 + 1)
  3310. +            p.frags = team2;
  3311. +        else if (p.team == TEAM_COLOR3 + 1)
  3312. +            p.frags = team3;
  3313. +        else if (p.team == TEAM_COLOR4 + 1)
  3314. +            p.frags = team4;
  3315. +        p = find(p, classname, "player");
  3316. +    }
  3317. +};
  3318. +
  3319. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/telefrag.qc src/telefrag.qc
  3320. --- v106qc/telefrag.qc    Wed Dec 31 19:00:00 1969
  3321. +++ src/telefrag.qc    Mon Oct  7 20:42:27 1996
  3322. @@ -0,0 +1,61 @@
  3323. +/*
  3324. +**
  3325. +** _telefrg.qc (Telefrag Code, 1.1)
  3326. +**
  3327. +** Copyright (C) 1996 Johannes Plass
  3328. +**
  3329. +** This program is free software; you can redistribute it and/or modify
  3330. +** it under the terms of the GNU General Public License as published by
  3331. +** the Free Software Foundation; either version 2 of the License, or
  3332. +** (at your option) any later version.
  3333. +**
  3334. +** This program is distributed in the hope that it will be useful,
  3335. +** but WITHOUT ANY WARRANTY; without even the implied warranty of
  3336. +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3337. +** GNU General Public License for more details.
  3338. +**
  3339. +** You should have received a copy of the GNU General Public License
  3340. +** along with this program; if not, write to the Free Software
  3341. +** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  3342. +**
  3343. +** Author:   Johannes Plass (plass@dipmza.physik.uni-mainz.de)
  3344. +**
  3345. +** --
  3346. +** Sniped by Zoid for ThreeWave Mods, GPL respected
  3347. +**
  3348. +*/
  3349. +
  3350. +entity() SelectSpawnPoint;
  3351. +
  3352. +entity(entity spot) TelefragSelectSpawnPoint =
  3353. +{
  3354. +    local entity e, firstspot;
  3355. +    local float search_spot;
  3356. +
  3357. +    search_spot = 25;
  3358. +    firstspot = spot;
  3359. +
  3360. +    while (search_spot) {
  3361. +        e = findradius(spot.origin, 100);
  3362. +        if (!e)
  3363. +            search_spot = 0;
  3364. +        else {
  3365. +            local float occupied;
  3366. +            occupied = 0;
  3367. +            while (!occupied && !(!e)) {
  3368. +                if (e.classname == "player" && e.deadflag == DEAD_NO)
  3369. +                        occupied = 1;
  3370. +                else
  3371. +                    e = e.chain;
  3372. +            }
  3373. +            if (occupied) {
  3374. +                spot = SelectSpawnPoint();
  3375. +                search_spot = search_spot - 1;
  3376. +                if (spot == firstspot)
  3377. +                        search_spot = 0;
  3378. +            } else
  3379. +                search_spot = 0;
  3380. +        }
  3381. +    }
  3382. +    return (spot);
  3383. +};
  3384. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/triggers.qc src/triggers.qc
  3385. --- v106qc/triggers.qc    Thu Sep 26 11:15:40 1996
  3386. +++ src/triggers.qc    Sun Oct  6 15:01:39 1996
  3387. @@ -381,7 +381,6 @@
  3388.  // only teleport living creatures
  3389.      if (other.health <= 0 || other.solid != SOLID_SLIDEBOX)
  3390.          return;
  3391. -
  3392.      SUB_UseTargets ();
  3393.  
  3394.  // put a tfog where the player was
  3395. @@ -405,13 +404,14 @@
  3396.          other.velocity = (v_forward * other.velocity_x) + (v_forward * other.velocity_y);
  3397.          return;
  3398.      }
  3399. -
  3400.      setorigin (other, t.origin);
  3401.      other.angles = t.mangle;
  3402. +
  3403.      if (other.classname == "player")
  3404.      {
  3405.          other.fixangle = 1;        // turn this way immediately
  3406.          other.teleport_time = time + 0.7;
  3407. +
  3408.          if (other.flags & FL_ONGROUND)
  3409.              other.flags = other.flags - FL_ONGROUND;
  3410.          other.velocity = v_forward * 300;
  3411. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/weapons.qc src/weapons.qc
  3412. --- v106qc/weapons.qc    Mon Sep 30 03:08:08 1996
  3413. +++ src/weapons.qc    Wed Oct  9 21:37:50 1996
  3414. @@ -5,11 +5,16 @@
  3415.  void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
  3416.  void(vector org, vector vel, float damage) SpawnBlood;
  3417.  void() SuperDamageSound;
  3418. +void() HasteSound;
  3419.  
  3420. +//Flamethrower
  3421. +void () W_FireFlame;
  3422.  
  3423.  // called by worldspawn
  3424.  void() W_Precache =
  3425.  {
  3426. +    precache_sound ("hknight/hit.wav");  // flamethrower
  3427. +
  3428.      precache_sound ("weapons/r_exp3.wav");    // new rocket explosion
  3429.      precache_sound ("weapons/rocket1i.wav");    // spike gun
  3430.      precache_sound ("weapons/sgun1.wav");
  3431. @@ -22,6 +27,9 @@
  3432.      precache_sound ("weapons/grenade.wav");    // grenade launcher
  3433.      precache_sound ("weapons/bounce.wav");        // grenade bounce
  3434.      precache_sound ("weapons/shotgn2.wav");    // super shotgun
  3435. +        precache_sound2 ("blob/land1.wav");     // chain go splorch!
  3436. +        precache_sound ("plats/medplat1.wav");  // chain cranking out
  3437. +        precache_sound ("doors/ddoor1.wav");    // chain cranking in
  3438.  };
  3439.  
  3440.  float() crandom =
  3441. @@ -767,6 +775,12 @@
  3442.          self.weaponmodel = "progs/v_axe.mdl";
  3443.          self.weaponframe = 0;
  3444.      }
  3445. +    else if (self.weapon == IT_HOOK)
  3446. +    {
  3447. +        self.currentammo = 0;
  3448. +        self.weaponmodel = "progs/v_axe.mdl";
  3449. +        self.weaponframe = 0;
  3450. +    }
  3451.      else if (self.weapon == IT_SHOTGUN)
  3452.      {
  3453.          self.currentammo = self.ammo_shells;
  3454. @@ -809,6 +823,13 @@
  3455.          self.weaponframe = 0;
  3456.          self.items = self.items | IT_ROCKETS;
  3457.      }
  3458. +    else if (self.weapon == IT_FLAMETHROWER)
  3459. +    {
  3460. +        self.currentammo = self.ammo_shells;
  3461. +        self.weaponmodel = "progs/v_rock.mdl";
  3462. +        self.weaponframe = 0;
  3463. +        self.items = self.items | IT_SHELLS;
  3464. +    }
  3465.      else if (self.weapon == IT_LIGHTNING)
  3466.      {
  3467.          self.currentammo = self.ammo_cells;
  3468. @@ -848,7 +869,7 @@
  3469.      if (self.currentammo > 0)
  3470.          return TRUE;
  3471.  
  3472. -    if (self.weapon == IT_AXE)
  3473. +    if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
  3474.          return TRUE;
  3475.      
  3476.      self.weapon = W_BestWeapon ();
  3477. @@ -874,6 +895,8 @@
  3478.  void()    player_nail1;
  3479.  void()    player_light1;
  3480.  void()    player_rocket1;
  3481. +void()    player_chain1;
  3482. +void()  player_chain3;
  3483.  
  3484.  void() W_Attack =
  3485.  {
  3486. @@ -897,18 +920,33 @@
  3487.              player_axec1 ();
  3488.          else
  3489.              player_axed1 ();
  3490. +        // RUNE: rune of hell magic
  3491. +        if (self.player_flag & ITEM_RUNE3_FLAG) {
  3492. +            self.attack_finished = time + 0.3;
  3493. +            HasteSound();
  3494. +        } else
  3495.          self.attack_finished = time + 0.5;
  3496.      }
  3497.      else if (self.weapon == IT_SHOTGUN)
  3498.      {
  3499.          player_shot1 ();
  3500.          W_FireShotgun ();
  3501. +        // RUNE: rune of hell magic
  3502. +        if (self.player_flag & ITEM_RUNE3_FLAG) {
  3503. +            self.attack_finished = time + 0.3;
  3504. +            HasteSound();
  3505. +        } else
  3506.          self.attack_finished = time + 0.5;
  3507.      }
  3508.      else if (self.weapon == IT_SUPER_SHOTGUN)
  3509.      {
  3510.          player_shot1 ();
  3511.          W_FireSuperShotgun ();
  3512. +        // RUNE: rune of hell magic
  3513. +        if (self.player_flag & ITEM_RUNE3_FLAG) {
  3514. +            self.attack_finished = time + 0.4;
  3515. +            HasteSound();
  3516. +        } else
  3517.          self.attack_finished = time + 0.7;
  3518.      }
  3519.      else if (self.weapon == IT_NAILGUN)
  3520. @@ -923,20 +961,48 @@
  3521.      {
  3522.          player_rocket1();
  3523.          W_FireGrenade();
  3524. +        // RUNE: rune of hell magic
  3525. +        if (self.player_flag & ITEM_RUNE3_FLAG) {
  3526. +            self.attack_finished = time + 0.3;
  3527. +            HasteSound();
  3528. +        } else
  3529.          self.attack_finished = time + 0.6;
  3530.      }
  3531.      else if (self.weapon == IT_ROCKET_LAUNCHER)
  3532.      {
  3533.          player_rocket1();
  3534.          W_FireRocket();
  3535. +        // RUNE: rune of hell magic
  3536. +        if (self.player_flag & ITEM_RUNE3_FLAG) {
  3537. +            self.attack_finished = time + 0.4;
  3538. +            HasteSound();
  3539. +        } else
  3540.          self.attack_finished = time + 0.8;
  3541.      }
  3542. +// Flamethrower
  3543. +    else if (self.weapon == IT_FLAMETHROWER)
  3544. +    {
  3545. +        player_shot1();
  3546. +        W_FireFlame();
  3547. +        if (self.waterlevel >2)
  3548. +            self.attack_finished = time + 1;
  3549. +        else
  3550. +            self.attack_finished = time + 0.1;
  3551. +    }
  3552.      else if (self.weapon == IT_LIGHTNING)
  3553.      {
  3554.          player_light1();
  3555.          self.attack_finished = time + 0.1;
  3556.          sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
  3557.      }
  3558. +    else if (self.weapon == IT_HOOK)
  3559. +    {
  3560. +        if (!self.hook_out)
  3561. +            player_chain1();
  3562. +        else
  3563. +            player_chain3();
  3564. +        self.attack_finished = time + 0.1;
  3565. +    }
  3566.  };
  3567.  
  3568.  /*
  3569. @@ -952,51 +1018,52 @@
  3570.      it = self.items;
  3571.      am = 0;
  3572.      
  3573. -    if (self.impulse == 1)
  3574. -    {
  3575. +    if (self.impulse == 1) {
  3576. +        if (self.weapon == IT_AXE)
  3577. +            fl = IT_HOOK;
  3578. +        else
  3579.          fl = IT_AXE;
  3580. -    }
  3581. -    else if (self.impulse == 2)
  3582. -    {
  3583. +    } else if (self.impulse == 2) {
  3584.          fl = IT_SHOTGUN;
  3585.          if (self.ammo_shells < 1)
  3586.              am = 1;
  3587. -    }
  3588. -    else if (self.impulse == 3)
  3589. -    {
  3590. +    } else if (self.impulse == 3) {
  3591.          fl = IT_SUPER_SHOTGUN;
  3592.          if (self.ammo_shells < 2)
  3593.              am = 1;
  3594. -    }        
  3595. -    else if (self.impulse == 4)
  3596. -    {
  3597. +    } else if (self.impulse == 4) {
  3598.          fl = IT_NAILGUN;
  3599.          if (self.ammo_nails < 1)
  3600.              am = 1;
  3601. -    }
  3602. -    else if (self.impulse == 5)
  3603. -    {
  3604. +    } else if (self.impulse == 5) {
  3605.          fl = IT_SUPER_NAILGUN;
  3606.          if (self.ammo_nails < 2)
  3607.              am = 1;
  3608. -    }
  3609. -    else if (self.impulse == 6)
  3610. -    {
  3611. +    } else if (self.impulse == 6) {
  3612. +        if (self.weapon != IT_GRENADE_LAUNCHER && self.ammo_rockets > 0) {
  3613.          fl = IT_GRENADE_LAUNCHER;
  3614.          if (self.ammo_rockets < 1)
  3615.              am = 1;
  3616. -    }
  3617. -    else if (self.impulse == 7)
  3618. -    {
  3619. +        } else if (self.ammo_shells > 1) {
  3620. +                fl = IT_FLAMETHROWER;
  3621. +                if (self.ammo_shells < 1)
  3622. +                    am = 1;
  3623. +        } else 
  3624. +            am = 1;
  3625. +    } else if (self.impulse == 7) {
  3626.          fl = IT_ROCKET_LAUNCHER;
  3627.          if (self.ammo_rockets < 1)
  3628.              am = 1;
  3629. -    }
  3630. -    else if (self.impulse == 8)
  3631. -    {
  3632. +    } else if (self.impulse == 8) {
  3633.          fl = IT_LIGHTNING;
  3634.          if (self.ammo_cells < 1)
  3635.              am = 1;
  3636. +    } else if (self.impulse == 22) {
  3637. +        fl = IT_HOOK;
  3638. +    } else if (self.impulse == 50) {
  3639. +        fl = IT_FLAMETHROWER;
  3640. +        if (self.ammo_shells < 1)
  3641. +            am = 1;
  3642.      }
  3643.  
  3644.      self.impulse = 0;
  3645. @@ -1017,6 +1084,15 @@
  3646.  // set weapon, set ammo
  3647.  //
  3648.      self.weapon = fl;        
  3649. +    if (self.weapon == IT_FLAMETHROWER)
  3650. +        sprint (self,"Flamethrower selected.\n");
  3651. +    else if (self.weapon == IT_GRENADE_LAUNCHER)
  3652. +        sprint (self,"Grenade Launcher selected.\n");
  3653. +    else if (self.weapon == IT_AXE)
  3654. +        sprint(self, "Axe selected.\n");
  3655. +    else if (self.weapon == IT_HOOK)
  3656. +        sprint(self, "Grappling hook selected.\n");
  3657. +
  3658.      W_SetCurrentAmmo ();
  3659.  };
  3660.  
  3661. @@ -1035,11 +1111,13 @@
  3662.      self.ammo_shells = 100;
  3663.      self.items = self.items | 
  3664.          IT_AXE |
  3665. +        IT_HOOK |
  3666.          IT_SHOTGUN |
  3667.          IT_SUPER_SHOTGUN |
  3668.          IT_NAILGUN |
  3669.          IT_SUPER_NAILGUN |
  3670.          IT_GRENADE_LAUNCHER |
  3671. +                IT_FLAMETHROWER |
  3672.          IT_ROCKET_LAUNCHER |
  3673.          IT_KEY1 | IT_KEY2;
  3674.  
  3675. @@ -1069,48 +1147,37 @@
  3676.      {
  3677.          am = 0;
  3678.  
  3679. -        if (self.weapon == IT_LIGHTNING)
  3680. -        {
  3681. +        if (self.weapon == IT_LIGHTNING) {
  3682.              self.weapon = IT_AXE;
  3683. -        }
  3684. -        else if (self.weapon == IT_AXE)
  3685. -        {
  3686. +        } else if (self.weapon == IT_AXE) {
  3687. +            self.weapon = IT_HOOK;
  3688. +        } else if (self.weapon == IT_HOOK) {
  3689.              self.weapon = IT_SHOTGUN;
  3690.              if (self.ammo_shells < 1)
  3691.                  am = 1;
  3692. -        }
  3693. -        else if (self.weapon == IT_SHOTGUN)
  3694. -        {
  3695. +        } else if (self.weapon == IT_SHOTGUN) {
  3696.              self.weapon = IT_SUPER_SHOTGUN;
  3697.              if (self.ammo_shells < 2)
  3698.                  am = 1;
  3699. -        }        
  3700. -        else if (self.weapon == IT_SUPER_SHOTGUN)
  3701. -        {
  3702. +        } else if (self.weapon == IT_SUPER_SHOTGUN) {
  3703.              self.weapon = IT_NAILGUN;
  3704.              if (self.ammo_nails < 1)
  3705.                  am = 1;
  3706. -        }
  3707. -        else if (self.weapon == IT_NAILGUN)
  3708. -        {
  3709. +        } else if (self.weapon == IT_NAILGUN) {
  3710.              self.weapon = IT_SUPER_NAILGUN;
  3711.              if (self.ammo_nails < 2)
  3712.                  am = 1;
  3713. -        }
  3714. -        else if (self.weapon == IT_SUPER_NAILGUN)
  3715. -        {
  3716. +        } else if (self.weapon == IT_SUPER_NAILGUN) {
  3717.              self.weapon = IT_GRENADE_LAUNCHER;
  3718.              if (self.ammo_rockets < 1)
  3719.                  am = 1;
  3720. -        }
  3721. -        else if (self.weapon == IT_GRENADE_LAUNCHER)
  3722. -        {
  3723. -            self.weapon = IT_ROCKET_LAUNCHER;
  3724. +        } else if (self.weapon == IT_GRENADE_LAUNCHER) {
  3725. +            self.weapon = IT_FLAMETHROWER;
  3726.              if (self.ammo_rockets < 1)
  3727.                  am = 1;
  3728. -        }
  3729. -        else if (self.weapon == IT_ROCKET_LAUNCHER)
  3730. -        {
  3731. +        } else if (self.weapon == IT_FLAMETHROWER) {
  3732. +           self.weapon = IT_ROCKET_LAUNCHER;
  3733. +        } else if (self.weapon == IT_ROCKET_LAUNCHER) {
  3734.              self.weapon = IT_LIGHTNING;
  3735.              if (self.ammo_cells < 1)
  3736.                  am = 1;
  3737. @@ -1118,6 +1185,11 @@
  3738.      
  3739.          if ( (it & self.weapon) && am == 0)
  3740.          {
  3741. +                        if (self.weapon == IT_FLAMETHROWER)
  3742. +                                sprint(self,"Flamethrower\n");
  3743. +                        else if (self.weapon == IT_GRENADE_LAUNCHER)
  3744. +                                sprint(self,"Grenade Launcher\n");
  3745. +
  3746.              W_SetCurrentAmmo ();
  3747.              return;
  3748.          }
  3749. @@ -1181,6 +1253,10 @@
  3750.          }
  3751.          else if (self.weapon == IT_SHOTGUN)
  3752.          {
  3753. +            self.weapon = IT_HOOK;
  3754. +        }
  3755. +        else if (self.weapon == IT_HOOK)
  3756. +        {
  3757.              self.weapon = IT_AXE;
  3758.          }
  3759.          else if (self.weapon == IT_AXE)
  3760. @@ -1221,27 +1297,100 @@
  3761.      dprint ("quad cheat\n");
  3762.  };
  3763.  
  3764. +void() PrintLocation =
  3765. +{
  3766. +    local string p;
  3767. +
  3768. +    p = vtos(self.origin);
  3769. +
  3770. +    sprint(self, "You are at ");
  3771. +    sprint(self, p);
  3772. +    sprint(self, "\n");
  3773. +};
  3774. +
  3775.  /*
  3776.  ============
  3777.  ImpulseCommands
  3778.  
  3779.  ============
  3780.  */
  3781. +//ZOID: Note, changed it all to an if/else construct.  No need to check
  3782. +//remaining impulses if we have one already.  Much cleaner and a tad
  3783. +//more efficient.  Using a non-existant impulse is still the worst case. :(
  3784.  void() ImpulseCommands =
  3785.  {
  3786. -    if (self.impulse >= 1 && self.impulse <= 8)
  3787. +     if ((self.impulse >= 1 && self.impulse <= 8) || self.impulse == 22 ||
  3788. +         self.impulse == 50)
  3789.          W_ChangeWeapon ();
  3790.  
  3791. -    if (self.impulse == 9)
  3792. +    else if (self.impulse == 9)
  3793.          CheatCommand ();
  3794. -    if (self.impulse == 10)
  3795. +
  3796. +    else if (self.impulse == 10)
  3797.          CycleWeaponCommand ();
  3798. -    if (self.impulse == 11)
  3799. +
  3800. +    else if (self.impulse == 11)
  3801.          ServerflagsCommand ();
  3802. -    if (self.impulse == 12)
  3803. +
  3804. +    else if (self.impulse == 12)
  3805.          CycleWeaponReverseCommand ();
  3806.  
  3807. -    if (self.impulse == 255)
  3808. +    else if (self.impulse == 99)
  3809. +        PrintLocation();
  3810. +        
  3811. +// *TEAMPLAY*
  3812. +// If we're allowed to drop items, enable impulse 20 and 21
  3813. +    else if ((teamplay & TEAM_DROP_ITEMS) && self.impulse == 20)
  3814. +        TossBackpack ();
  3815. +
  3816. +    else if ((teamplay & TEAM_DROP_ITEMS) && self.impulse == 21)
  3817. +        TossWeapon ();
  3818. +
  3819. +// *TEAMPLAY*
  3820. +// Impulse 25 prints info about the current teamplay settings.
  3821. +    else if (self.impulse == 25)
  3822. +        TeamPrintSettings ();
  3823. +
  3824. +// ** M U L T I S K I N  1.1  (start)
  3825. +
  3826. +// modified to not work in teamplay by Zoid, since you can't tell what color
  3827. +// people are
  3828. +    else if ((teamplay == 0) && ((self.impulse == 200) || (self.impulse == 201))) {
  3829. +        if (self.impulse == 200) {
  3830. +            self.skin = self.skin + 1;
  3831. +            if (self.skin == 19) 
  3832. +                self.skin = 0;
  3833. +        } else if (self.impulse == 201) {
  3834. +            self.skin = self.skin - 1;
  3835. +            if (self.skin == -1) 
  3836. +                self.skin = 18;
  3837. +        }
  3838. +        self.player_flag = self.player_flag - (self.player_flag & 65280);
  3839. +        self.player_flag = self.player_flag | (self.skin * 256);  
  3840. +        if (self.skin == 0) centerprint(self, "SKIN: Quake himself (1)"); else
  3841. +        if (self.skin == 1) centerprint(self, "SKIN: Duke Nukem 3d (2)"); else
  3842. +        if (self.skin == 2) centerprint(self, "SKIN: Mr. Toad (3)"); else
  3843. +        if (self.skin == 3) centerprint(self, "SKIN: the Stormtrooper (4)"); else
  3844. +        if (self.skin == 4) centerprint(self, "SKIN: Max (5)"); else
  3845. +        if (self.skin == 5) centerprint(self, "SKIN: the Terminator (6)"); else
  3846. +        if (self.skin == 6) centerprint(self, "SKIN: Judge Dredd (7)"); else
  3847. +        if (self.skin == 7) centerprint(self, "SKIN: Camouflaged soldier (8)"); else
  3848. +        if (self.skin == 8) centerprint(self, "SKIN: Captain Picard (9)"); else
  3849. +        if (self.skin == 9) centerprint(self, "SKIN: the Wizzard (10)"); else
  3850. +        if (self.skin == 10) centerprint(self,"SKIN: the Predator (11)"); else
  3851. +        if (self.skin == 11) centerprint(self,"SKIN: Skeleton (12)"); else
  3852. +        if (self.skin == 12) centerprint(self,"SKIN: Wan-Fu (13)"); else
  3853. +        if (self.skin == 13) centerprint(self,"SKIN: Henry Rollins (14)"); else
  3854. +        if (self.skin == 14) centerprint(self,"SKIN: He-Man (15)"); else
  3855. +        if (self.skin == 15) centerprint(self,"SKIN: Boba (16)"); else
  3856. +        if (self.skin == 16) centerprint(self,"SKIN: Superman (17)"); else
  3857. +        if (self.skin == 17) centerprint(self,"SKIN: NYPD Cop (18)"); else
  3858. +        if (self.skin == 18) centerprint(self,"SKIN: Red/Yellow women dude (19)");
  3859. +    }
  3860. +
  3861. +// ** M U L T I S K I N  1.1  (end)
  3862. +
  3863. +    else if (self.impulse == 255)
  3864.          QuadCheat ();
  3865.          
  3866.      self.impulse = 0;
  3867. @@ -1259,6 +1408,11 @@
  3868.      if (time < self.attack_finished)
  3869.          return;
  3870.  
  3871. +//ZOID: Only call ImpulseCommands() if needed!  This saves a good chunk
  3872. +//of cpu.  'profile' in console listed ImpulseCommands() as #1 user of
  3873. +//cpu (instructions), adding this one line caused it to not even be in
  3874. +//the top ten.
  3875. +    if (self.impulse)
  3876.      ImpulseCommands ();
  3877.      
  3878.  // check for attack
  3879. @@ -1278,10 +1432,9 @@
  3880.  */
  3881.  void() SuperDamageSound =
  3882.  {
  3883. -    if (self.super_damage_finished > time)
  3884. -    {
  3885. -        if (self.super_sound < time)
  3886. -        {
  3887. +// RUNE play super damage sound if player has Black Magic, too
  3888. +    if (self.super_damage_finished > time || (self.player_flag & ITEM_RUNE2_FLAG)) {
  3889. +        if (self.super_sound < time) {
  3890.              self.super_sound = time + 1;
  3891.              sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
  3892.          }
  3893. @@ -1289,4 +1442,41 @@
  3894.      return;
  3895.  };
  3896.  
  3897. +/*
  3898. +========
  3899. +RegenerationSound
  3900. +
  3901. +Plays sound if needed
  3902. +========
  3903. +*/
  3904. +void() RegenerationSound =
  3905. +{
  3906. +// RUNE play healing sound if player has Elder Magic
  3907. +    if (self.player_flag & ITEM_RUNE4_FLAG) {
  3908. +        if (self.regeneration_sound < time) {
  3909. +            self.regeneration_sound = time + 1;
  3910. +            sound(self, CHAN_BODY, "items/r_item1.wav", 1, ATTN_NORM);
  3911. +        }
  3912. +    }
  3913. +    return;
  3914. +};
  3915. +
  3916. +/*
  3917. +========
  3918. +HasteSound
  3919. +
  3920. +Plays sound if needed
  3921. +========
  3922. +*/
  3923. +void() HasteSound =
  3924. +{
  3925. +// RUNE play haste (Chthon's roar) sound if player has Hell Magic
  3926. +    if (self.player_flag & ITEM_RUNE3_FLAG) {
  3927. +        if (self.haste_sound < time) {
  3928. +            self.haste_sound = time + 2;
  3929. +            sound(self, CHAN_BODY, "boss1/sight1.wav", 1, ATTN_NORM);
  3930. +        }
  3931. +    }
  3932. +    return;
  3933. +};
  3934.  
  3935. diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/world.qc src/world.qc
  3936. --- v106qc/world.qc    Thu Sep 26 11:15:40 1996
  3937. +++ src/world.qc    Sat Oct 12 20:44:33 1996
  3938. @@ -172,6 +172,10 @@
  3939.  void() worldspawn =
  3940.  {
  3941.      lastspawn = world;
  3942. +    runespawn = world;
  3943. +    runespawned = 0;
  3944. +    capturespawned = 0;
  3945. +    teamscored = 0;
  3946.      InitBodyQue ();
  3947.  
  3948.  // custom map attributes
  3949. @@ -241,6 +245,7 @@
  3950.      precache_sound ("weapons/ax1.wav");            // ax swoosh
  3951.      precache_sound ("player/axhit1.wav");        // ax hit meat
  3952.      precache_sound ("player/axhit2.wav");        // ax hit world
  3953. +    precache_sound ("hknight/hit.wav");            // ZOID: hook launch
  3954.  
  3955.      precache_sound ("player/h2ojump.wav");        // player jumping into water
  3956.      precache_sound ("player/slimbrn2.wav");        // player enter slime
  3957. @@ -282,12 +287,23 @@
  3958.      precache_model ("progs/spike.mdl");
  3959.      precache_model ("progs/s_spike.mdl");
  3960.  
  3961. +// for hook
  3962. +    precache_model ("progs/v_spike.mdl");
  3963. +
  3964.      precache_model ("progs/backpack.mdl");
  3965.  
  3966.      precache_model ("progs/zom_gib.mdl");
  3967.  
  3968.      precache_model ("progs/v_light.mdl");
  3969.      
  3970. +// rune precache
  3971. +    precache_model ("progs/end1.mdl");
  3972. +    precache_model ("progs/end2.mdl");
  3973. +    precache_model ("progs/end3.mdl");
  3974. +    precache_model ("progs/end4.mdl");
  3975. +    precache_sound ("items/protect3.wav");
  3976. +    precache_sound ("items/r_item1.wav");
  3977. +    precache_sound ("boss1/sight1.wav");
  3978.  
  3979.  //
  3980.  // Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
  3981. @@ -377,6 +393,7 @@
  3982.  // respawned elsewhere
  3983.  void(entity ent) CopyToBodyQue =
  3984.  {
  3985. +    bodyque_head.skin = ent.skin;
  3986.      bodyque_head.angles = ent.angles;
  3987.      bodyque_head.model = ent.model;
  3988.      bodyque_head.modelindex = ent.modelindex;
  3989.